定点平方根函数错误结果为大数字

时间:2015-11-04 16:17:51

标签: c math floating fixed-point sqrt

你好朋友和敌人

我从一个名为libfixmath的库中获得了这个平方根函数,这个函数效果很好,但是从32767.0f及以上它开始返回错误和否定的结果。我需要平方根的数字相当大,高达999999.0f。你们中的任何人都知道我能做些什么来解决问题吗?

#include <iostream>

float into_float(const int value) {
    return ((float)value / 65536.0f);
}

int from_float(const float value) {
    return (int)(value * 65536.0f);
}

int fp_sqrt(int value) {
    unsigned char neg = (value < 0);
    unsigned int num = (neg ? -value : value);
    unsigned int result = 0;
    unsigned int bit;
    unsigned char n;
    if (num & 0xFFF00000) {
        bit = (unsigned int)1 << 30;
    } else {
        bit = (unsigned int)1 << 18;
    }
    while (bit > num) bit >>= 2;
    for (n = 0; n < 2; n++) {
        while (bit) {
            if (num >= result + bit) {
                num -= result + bit;
                result = (result >> 1) + bit;
            } else {
                result = (result >> 1);
            }
            bit >>= 2;
        }
        if (n == 0) {
            if (num > 65535) {
                num -= result;
                num = (num << 16) - 0x8000;
                result = (result << 16) + 0x8000;
            } else {
                num <<= 16;
                result <<= 16;
            }
            bit = 1 << 14;
        }
    }
    if (num > result) {
        result++;
    }
    return (neg ? -result : result);
}

void main() {
    float flt_value = 32767.0f;
    int int_value = from_float(flt_value);
    float flt_root = sqrt(flt_value);
    int int_root = fp_sqrt(int_value);
    float flt_root2 = into_float(int_root);
    printf("sqrt: %f fp_sqrt: %f", flt_root, flt_root2);
    getchar();
}

谢谢你leppie,我改变了一些东西,现在可以使用大数字,我不确定我做的是完全正确但是在这里:

#include <iostream>

float into_float(const int value) {
    return ((float)value / 65536.0f);
}

long long from_float(const float value) {
    return (long long)(value * 65536.0f);
}

long long fp_sqrt(long long value) {
    unsigned char neg = (value < 0);
    long long num = (neg ? -value : value);
    long long result = 0;
    long long bit;
    unsigned char n;
    if (num & 0xFFF00000) {
        bit = (long long)1 << 60;
    } else {
        bit = (long long)1 << 36;
    }
    while (bit > num) bit >>= 2;
    for (n = 0; n < 2; n++) {
        while (bit) {
            if (num >= result + bit) {
                num -= result + bit;
                result = (result >> 1) + bit;
            } else {
                result = (result >> 1);
            }
            bit >>= 2;
        }
        if (n == 0) {
            if (num > 65535) {
                num -= result;
                num = (num << 16) - 0x8000;
                result = (result << 16) + 0x8000;
            } else {
                num <<= 16;
                result <<= 16;
            }
            bit = 1 << 14;
        }
    }
    if (num > result) {
        result++;
    }
    return (neg ? -result : result);
}

void main() {
    float flt_value = 11932767.0f;
    long long ll_value = from_float(flt_value);
    float flt_root = sqrt(flt_value);
    int int_root = (int)fp_sqrt(ll_value);
    float flt_root2 = into_float(int_root);
    printf("sqrt: %f fp_sqrt: %f", flt_root, flt_root2);
    getchar();
}

0 个答案:

没有答案