c - 将用户的二进制输入转换为双精度值时出错
问题描述
所以下面我编写了代码来将二进制值转换为它的双重等价物。然而,
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;
}
解决方案
示例输入字符串"0111111111111111111111111111111111111111111111111111111111111111"
对应于 IEEE-754 双 NaN(非数字)值。字符串的指数部分"11111111111"
对应于 1024 的 (radix-2) 指数加上 1023 的零偏移偏差。但是 IEEE-754 有限数值的最大 (radix-2) 指数为 1023。输出-of-range 指数导致在2047时pow(2, exponent-1023)
返回(此处包括 1023 的零偏移)。inf
exponent
exponent
IEEE-754DBL_MAX
值由输入字符串表示"0111111111101111111111111111111111111111111111111111111111111111"
。
从输入字符串中提取有效数字(尾数)值的代码过早终止:
double summingMantissa = 0;
for(int i =12; i<52; i++) {
if (usersBinVal[i] == '1') {
summingMantissa = summingMantissa + pow(2, 11-i);
}
}
终止条件应该是i<64
。
推荐阅读
- path-finding - 从 Godot 中的 Curve3D (Path) 获取手动定义的向量
- ios - iOS 存储 SQLite 数据库
- c# - gRPC 间歇性地具有高延迟
- javascript - 选项卡:数据切换不展开数据
- android - Wifi状态不会在android中改变?
- keyboard - Android WebVIew中的键盘长键按下
- django - JSONField order_by 查询名称中带有标点的字段的问题
- c# - C# 无法使用可观察集合绑定到列表视图
- testing - 赛普拉斯:使用 npm run cy:open 从命令行传递环境变量
- windows - .bat curl with 用于抱怨(此时出乎意料