C言語関係掲示板

過去ログ

No.1074 8バイト整数の加算、減算、除算

[戻る] [ホームページ]
No.14085

8バイト整数の加算、減算、除算
投稿者---hatton(2004/05/18 10:56:46)


H8/3048 のCコンパイラ (HEW) を使用しています。

Signed Long (4 Bytes) データの移動平均を行いたいのですが
平均数が多いため、加算結果を格納するのに Signed Long (4 Bytes) では
バイト数が足りない状況です。

(全て符号つき)
加算: 8 Bytes + 4 Bytes = 8 Bytes
減算: 8 Bytes - 4 Bytes = 8 Bytes
除算: 8 Bytes / 4 Bytes = 4 Bytes

を行いたいのです。

実装方法を教えて頂けませんでしょうか。
よろしくお願いいたします。


No.14086

Re:8バイト整数の加算、減算、除算
投稿者---かずま(2004/05/18 20:23:04)


オーバーフローを無視すれば、こんなプログラムになりましたが、
これでよろしいでしょうか?
typedef long int32;
typedef unsigned long uint32;
typedef struct { uint32 hi, lo; } int64;

int64 add64(int64 a, int32 b)
{
    if (b < 0) a.hi--;
    a.lo += (uint32)b;
    if (a.lo < (uint32)b) a.hi++;
    return a;
}

int64 sub64(int64 a, int32 b)
{
    return add64(a, -b);
}

static int64 neg64(int64 a)
{
    if (a.lo)
        a.hi = ~a.hi, a.lo = 0 - a.lo;
    else
        a.hi = 0 - a.hi;
    return a;
}

static uint32 udiv(int64 a, uint32 b)
{
    uint32 q = 0;  int i;

    for (i = 0; i < 32; i++) {
        a.hi <<= 1;
        if (a.lo >> 31) a.hi++;
        a.lo <<= 1;
        q <<= 1;
        if (a.hi >= b) q += 1, a.hi -= b;
    }
    return q;
}

int32 div64(int64 a, int32 b)
{
    int neg = 0;

    if (a.hi >> 31) neg = 1, a = neg64(a);
    if (b < 0) neg ^= 1, b = -b;
    b = udiv(a, b);
    return neg ? -b : b;
}


/* 以下、テストプログラム */

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

void print(int64 a)
{
    double d; int neg = 0;

    if (a.hi >> 31) neg = 1, a = neg64(a);
    d = a.hi * 4294967296.0 + a.lo;
    if (neg) d = -d;
    printf("%.f\n", d);
}

int main(void)
{
    int64 a, x;  int32 b;  double d;  int neg = 0;

    while (scanf("%lf %d", &d, &b) == 2) {
        if (d < 0) neg = 1, d = -d;
        a.hi = d / 4294967296.0;
        a.lo = fmod(d, 4294967296.0);
        if (neg) a = neg64(a);
        x = add64(a, b); printf("add: "); print(x);
        x = sub64(a, b); printf("sub: "); print(x);
        b = div64(a, b); printf("div: %d\n", b);
    }
    return 0;
}



No.14088

Re:8バイト整数の加算、減算、除算
投稿者---かずま(2004/05/18 23:23:36)


> オーバーフローを無視すれば、こんなプログラムになりましたが、
> これでよろしいでしょうか?

テストプログラムの int neg = 0; は while ループの中に入れないと
いけませんね。

それから、q += 1 と書いてしまったところがありますが、これは q++ でも
かまいません。


No.14089

↑ ありがとうございます。
投稿者---hatton(2004/05/19 09:26:15)


かずまさん、ソースをご提供下さり、ありがとうございます。

大変助かりました。内容については、これから勉強いたします。
ありがとうございました。