【问题标题】:Error with converting a binary input from the user into a double value将用户的二进制输入转换为双精度值时出错
【发布时间】:2021-12-22 09:34:59
【问题描述】:

所以下面我编写了将二进制值转换为其双精度值的代码。然而,

binConversionDouble("0111111111111111111111111111111111111111111111111111111111111111")

给予:

179769313486149841153851976955417028335471708986564534469802644816832731470450734933617524554272984142853535521554773891036051644209223511432842829043130247900910146729889177843938143131935935774382721844130004287345894163215696051477671359689698349651554878795894806567601614971014045300870721438977577975808.000000

但 DBL_MAX 的实际值为:

179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000

我的逻辑似乎是正确的,但我不确定上述是否是算术计算精度损失或我的逻辑缺陷的情况。有人可以指导我为什么这两个值不同吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <limits.h>
#include <math.h>
#include <float.h>

double binConvertDouble(const double *mainBinArr, const char usersBinVal[]) {

    double isNegative = 1;
    if (usersBinVal[0] == '1') {isNegative = -1;}

    double exponent = 0;
    char exponentSubString[12];
    int count = 0;
    for(int i =0; i<11; i++) {
        exponentSubString[i] = usersBinVal[i+1];
        count = count + 1;
    }
    exponentSubString[11] = '\0';
    exponent = calculatingDoublesExp(mainBinArr, exponentSubString);

    double summingMantissa = 0;
    for(int i =12; i<52; i++) {
        if (usersBinVal[i] == '1') {
            summingMantissa = summingMantissa + pow(2, 11-i);
        }
    }
    double totalMantissaVal = 0;
    totalMantissaVal = 1 + summingMantissa;
    double actualExp = pow(2, (exponent-1023));
    double finalVal = isNegative * totalMantissaVal * actualExp;
    return finalVal;
}


int main() {
  printf("VALUE WE GET %f\n", binConversionDouble("0111111111111111111111111111111111111111111111111111111111111111"));
return 0;
}

【问题讨论】:

  • 你做了什么来调试你的代码?请edit您的问题添加新信息,请勿添加评论。
  • 为了重现问题真的需要所有这些代码吗?如果可能,请提供minimal reproducible example,并强调“最小”一词。请阅读提供的链接中的说明,以获取有关如何创建此类示例的指导。
  • 您是否尝试过在调试器中逐行运行代码,同时监控所有变量的值,以确定您的程序在哪个点停止按预期运行?如果您没有尝试过,那么您可能想阅读以下内容:What is a debugger and how can it help me diagnose problems? 即使使用调试器并不能真正解决问题,它至少应该可以帮助您隔离问题并创建问题的minimal reproducible example ,以便其他人更容易帮助您。
  • 输入字符串表示一个 IEEE-754 NaN 值。 DBL_MAX 将由输入字符串 "0111111111101111111111111111111111111111111111111111111111111111" 表示。
  • "但是,binConversionDouble("0111111111111111111111111111111111111111111111111111111111111111") 给出的是 inf 而不是 DBL_MAX。 --> avii,为什么你认为这会导致DBL_MAX?它不应该。 DBL_MAX 有不同的二进制文件。

标签: c binary double


【解决方案1】:

示例输入字符串 "0111111111111111111111111111111111111111111111111111111111111111" 对应于 IEEE-754 双 NaN(非数字)值。字符串的指数部分是"11111111111",对应于 1024 的 (radix-2) 指数加上 1023 的零偏移偏差。但是 IEEE-754 有限数值的最大 (radix-2) 指数为 1023 . 超出范围的指数导致pow(2, exponent-1023) 在exponent 为2047 时返回inf(exponent 在此处包括1023 的零偏移)。

IEEE-754 DBL_MAX 值由输入字符串 "0111111111101111111111111111111111111111111111111111111111111111" 表示。

从输入字符串中提取有效数字(尾数)值的代码过早终止:

    double summingMantissa = 0;
    for(int i =12; i<52; i++) {
        if (usersBinVal[i] == '1') {
            summingMantissa = summingMantissa + pow(2, 11-i);
        }
    }

终止条件应该是i&lt;64。

【讨论】:

    猜你喜欢
    • 2011-01-14
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多