2013年12月13日金曜日

開発環境

C実践プログラミング 第3版 (Steve Oualline (著)、 望月 康司 (監訳) (翻訳)、谷口 功 (翻訳)、オライリー・ジャパン)のⅡ部(単純なプログラミング)の16章(浮動小数点数)、16.12(プログラミング実習)、実習 16-1を解いてみる。

その他参考書籍

実習16-1.

コード

sample.c

#include <stdio.h>
#include <math.h>
#include <string.h>

#define SIZE 10

int main()
{
    char *strings[] = {"+1.000E+", "+3.300E+4", "-8.223E-3", "+0.000E+0"};
    double nums[] = {1.0, 33000.0, -.008223, 0.0};
    char *s1, *s2;
    char s[SIZE];
    double a;
    double string2double(char *s);
    void double2string(char s[], double a);
    void add(char s[], char *l, char *r);
    void subtruct(char s[], char *l, char *r);
    void multiply(char s[], char *l, char *r);
    void divide(char s[], char *l, char *r);
    int i;
    for(i = 0; i < 4; i++){
        printf("%10s %15f\n", strings[i], string2double(strings[i]));
    }
    printf("\n");
    for(i = 0; i < 4; i++){
        double2string(s, nums[i]);
        printf("%10s %15f\n", s, nums[i]);
    }
    printf("\n");
    s1 = "+2.000E+0";
    s2 = "+3.000E-1";
    add(s, s1, s2);
    printf("%10s %15f, %10s %15f, 和 %s\n",
        s1, string2double(s1), s2, string2double(s2), s);
    s1 = "+2.000E+0";
    s2 = "+3.000E-1";
    subtruct(s, s1, s2);
    printf("%10s %15f, %10s %15f, 差 %s\n",
        s1, string2double(s1), s2, string2double(s2), s);
    s1 = "+1.200E-1";
    s2 = "+1.100E+1";
    multiply(s, s1, s2);
    printf("%10s %15f, %10s %15f, 積 %s\n",
        s1, string2double(s1), s2, string2double(s2), s);
    s1 = "+1.000E+2";
    s2 = "+3.000E+1";
    divide(s, s1, s2);
    printf("%10s %15f, %10s %15f, 商 %s\n",
        s1, string2double(s1), s2, string2double(s2), s);
    return (0);
}

double string2double(char *s)
{
    double a = 0;
    int pm1 = *s == '-' ? -1 : 1;
    char pm2;
    int n;
    s++;
    while(1){
        if (*s == '.'){
            s++;
        }
        a = a * 10 + (*s - '0');
        s++;
        if (*s == 'e' || *s == 'E'){
            break;
        }
    }
    s++;
    pm2 = *s;
    s++;
    n = '0' < *s && *s <= '9' ? *s - '0' : 0;
    a = pm2 == '-' ? a / pow(10, n) : a * pow(10, n);
    a /= pow(10, 3);
    return pm1 * a;
}

void double2string(char s[], double a)
{
    int n = 0;
    int i = 0;
    int j;
    char ch1, ch2;
    if (a == 0.0){
        strcpy(s, "+0.00E+0");
    } else {
        if(a < 0){
            s[i++] = '-';
            a *= -1;
        } else {
            s[i++] = '+';
        }
        if (a >= 10){
            while (a > 10){
                a /= 10;
                n++;
            }
        } else {
            while (a < 1 && n < 9){
                a *= 10;
                n--;
            }
        }
        s[i++] = (int) a + '0';
        s[i++] = '.';
        for(j = 0; j < 2; j++){
            a *= 10;
            s[i++] = ((int) a % 10) + '0';
        }
        a *= 10;
        ch1 = ((int) a % 10) + '0';
        ch2 = ((int) a % 10) + '0';
        s[i++] = ch2 >= '5' ? ch1 + 1 : ch1;
        s[i++] = 'E';
        s[i++] = n >= 0 ? '+' : '-';
        if (n < 0){
            n *= -1;
        }
        s[i++] = n + '0';
        s[i] = '\0';
    }
}

void add(char s[], char *l, char *r)
{
    double a = string2double(l);
    double b = string2double(r);
    double2string(s, a + b);
}

void subtruct(char *s, char *l, char *r)
{
    double a = string2double(l);
    double b = string2double(r);
    double2string(s, a - b);   
}

void multiply(char *s, char *l, char *r)
{
    double a = string2double(l);
    double b = string2double(r);
    double2string(s, a * b);   
}

void divide(char *s, char *l, char *r)
{
    double a = string2double(l);
    double b = string2double(r);
    double2string(s, a / b);   
}

makefile

CC=cc
CFLAGS=-g

sample: sample.c
 $(CC) $(CFLAGS) -o sample sample.c

clean:
 rm -f sample

入出力結果(Terminal)

$ make
cc -g -o sample sample.c
$ ./sample
  +1.000E+        1.000000
 +3.300E+4    33000.000000
 -8.223E-3       -0.008223
 +0.000E+0        0.000000

 +1.000E+0        1.000000
 +3.300E+4    33000.000000
 -8.223E-3       -0.008223
  +0.00E+0        0.000000

 +2.000E+0        2.000000,  +3.000E-1        0.300000, 和 +2.300E+0
 +2.000E+0        2.000000,  +3.000E-1        0.300000, 差 +1.700E+0
 +1.200E-1        0.120000,  +1.100E+1       11.000000, 積 +1.320E+0
 +1.000E+2      100.000000,  +3.000E+1       30.000000, 商 +3.333E+0
$

0 コメント:

コメントを投稿