Skip to content

Instantly share code, notes, and snippets.

@katsuobushiFPGA
Created May 5, 2015 14:48
Show Gist options
  • Save katsuobushiFPGA/8ea11e9c14f771d1b942 to your computer and use it in GitHub Desktop.
Save katsuobushiFPGA/8ea11e9c14f771d1b942 to your computer and use it in GitHub Desktop.
#pragma once
#pragma warning(disable: 4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 100
#define DISP(ary) for(int i=0;i<N;i++)printf("%d",ary[i]);
#define DISPRES(ary) for(int i=0;i<N*N;i++)printf("%c",ary[i]);
struct point {
int x;
int y;
int calc;
int sign;
};
void calamul(char*,char* ,char*,struct point);
void padding(int*,int);
int charToInt(char ch);
void dot_erase(char*);
void add(int *arg, int *arg2, int *res);
void multiple_one(int *arg, int arg2, int *res);
void multiple_complex(int*arg, int*arg2, int*res,int biglen);
void dot_insert(int* result, int dotlen);
int length(char*arg);
void reverse(char*arg);
void calamul(char* arg, char* arg2, char* res,struct point xyz) {
int i;
int kou1[N] = { 0 };
int kou2[N] = { 0 };
int result[N*N] = { 0 };
int arg_dotflag = 0;
int arg2_dotflag = 0;
int arg_intlen = xyz.x;
int arg2_intlen = xyz.y;
int arg_dotlen;
int arg2_dotlen;
char *p_arg = arg;
char *p_arg2=arg2;
/*小数点チェック*/
if (strchr(arg, '.') != NULL)
arg_dotflag = 1;
if (strchr(arg2, '.') != NULL)
arg2_dotflag = 1;
/*小数部分の長さを決める*/
(arg_dotflag == 1) ? arg_dotlen = strlen(arg) - xyz.x - 1 : arg_dotlen = 0;
(arg2_dotflag == 1) ? arg2_dotlen = strlen(arg2) - xyz.y - 1 : arg2_dotlen = 0;
/* charをint型配列に格納 (小数点は含めない)*/
for (i = 0; *p_arg != '\0'; p_arg++) {
if (*p_arg == '.')
continue;
kou1[i] = charToInt(*p_arg);
i++;
}
for (i = 0; *p_arg2 != '\0'; p_arg2++) {
if (*p_arg2 == '.')
continue;
kou2[i] = charToInt(*p_arg2);
i++;
}
/* 小数点を考慮して長さを決める */
int arglen = strlen(arg+arg_dotflag);
int arg2len = strlen(arg2+arg2_dotflag);
/* 右詰めにする */
padding(kou1, arglen);
padding(kou2, arg2len);
multiple_complex(kou1, kou2, result,N);
/*小数点合わせ*/
printf("小数部分:%d\n", arg_dotlen);
printf("小数部分:%d\n", arg2_dotlen);
dot_insert(result,arg_dotlen+arg2_dotlen);
/* char型に変換し,結果を逆順に格納 */
for (int tes = 0,i=N*N-1; tes < N*N; tes++,i--) {
res[tes] = (char)result[i] + 48;
}
int dot=0;
int end = 0;
/*dotの位置を割り出す*/
for (int i = 0; *(res + i) != '\0'; i++) {
if (*(res + i) == '.') {
dot = i;
break;
}
}
/*小数点以下がない場合*/
if (dot == 0){
for (int i = N*N-1; i>= 0; i--) {
if (*(res + i) != '0') {
end = i;
break;
}
}
}
else {
if (*(res + dot+1) == '0')
end = i;
else {
for (int i = dot; *(res + i) != '\0'; i++) {
if (*(res + i) == '0') {
end = --i;
break;
}
}
}
}
char*str;
if (end == 0)
str = NULL;
else
str = (char*)malloc(sizeof(char)*(end+1));
strncpy(str,res, end+1);
str[end + 1] = '\0';
/*クリア*/
for (int i = 0; i < N*N; i++) {
res[i] = '0';
}
reverse(str);
sprintf(res, str);
}
void reverse(char*arg) {
int len = length(arg);
int i, j;
for (i = len - 1,j=0; j < len / 2;j++ ,i--) {
char tmp = *(arg + i);
*(arg + i) = *(arg + j);
*(arg + j) = tmp;
}
}
int length(char*arg) {
int i = 0;
while (*(arg+i) != '\0') {
i++;
}
return i;
}
int charToInt(char ch) {
return ch - 48;
}
void dot_insert(int* result,int dotlen) {
int i, j=1;
int flag = 0;
if (dotlen <= 0)
return;
for (i = 1; i <= N*N - dotlen - 1; i++) {
result[i - 1] = result[i];
if (i == N*N - dotlen - 1)
result[i] = -2;
}
}
void padding(int* ary,int len) {
int i,j=1;
for (i = len - 1; i >= 0; i--,j++) {
int tmp = ary[N - j];
ary[N - j] = ary[i];
ary[i] = tmp;
}
}
void add(int *arg,int *arg2,int *res) {
int i, j=N*N-1,carry=0;
for (i = N*N-1; i >=0 ; i--) {
int ans = arg[i] + arg2[i] + carry;
if (ans / 10)
carry = ans / 10;
else
carry = 0;
res[j--] = ans % 10;
}
res[0] = carry;
}
void multiple_one(int *arg, int arg2, int* res) {
/* padding関数を通した後でないと正常に動作しない */
/* 配列の右から順に計算する */
int i,j=N*N-1,carry=0;
for (i = N - 1; i >= 0; i--) {
int ans = arg[i] * arg2 + carry;
if (ans / 10)
carry = ans / 10;
else
carry = 0;
res[j--] = ans % 10;
}
}
/*arg1とarg2の大きい方の長さを入れる*/
void multiple_complex(int*arg, int*arg2, int*res,int biglen){
int i, j,k,mov=0;
int tmp[N*N] = { 0 };
for (i = 1; i<=N; i++) {
multiple_one(arg, *(arg2 + N - i), tmp);
/*ずらす処理*/
for (k = 1; k <= mov; k++) {
for (j = 1; j < N*N ; j++) {
tmp[j - 1] = tmp[j];
tmp[j] = 0;
}
}
add(tmp, res, res);
mov++;
}
}
#include "Header.h"
int main()
{
char arg1[N] = "1.190";
char arg2[N] = "1.22";
char res[N*N] = { 0 };
struct point xyz = { 1, 1, 0, 0 };
calamul(arg1,arg2,res,xyz);
printf("%s", res);
getchar();
return 0;
}
@katsuobushiFPGA
Copy link
Author

コードを綺麗にしたい
多倍長演算:乗算

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment