如果我将单 s 转换为十进制 d 我发现它的位代码与直接创建小数。
例如:
Single s = 0.01f;
Decimal d = 0.01m;
int[] bitsSingle = Decimal.GetBits((decimal)s)
int[] bitsDecimal = Decimal.GetBits(d)
返回(为简洁起见,删除了中间元素):
bitsSingle: [0] = 10 [3] = 196608 bitsDecimal: [0] = 1 [3] = 131072
这两个都是十进制数,两者(看起来)都准确地代表0.01:
看看这个规范除了可能之外没有任何亮点:
§4.1.7与float和double数据类型相反,十进制小数 0.1之类的数字可以用十进制表示 表示。
建议在转换前单无法准确表示0.01,因此:
答案 0 :(得分:7)
两位小数精确表示0.1。只是decimal
格式允许多个按位不同的值表示完全相同的数字。
single
无法准确表示0.1。根据{{1}}:
GetBits
数字的二进制表示由1位组成 符号,96位整数,以及用于分割的缩放因子 整数,并指定它的小数部分。 缩放因子隐含地为数字10,提升为指数 范围从0到28。返回值是一个由32位有符号整数组成的四元素数组。
返回数组的第一个,第二个和第三个元素包含 96位整数的低,中,高32位。
返回数组的第四个元素包含比例因子和 标志。它由以下部分组成:
0到15位,低位字未使用,必须为零。
第16位至第23位必须包含0到28之间的指数 表示10的幂除以整数。
第24至30位未使用且必须为零。
位31包含符号:0表示正数,1表示负数。
请注意,位表示区分负数和 正零。这些值被视为完全相同 操作
示例中每个Decimal
的第四个整数为decimal
0x00030000
和bitsSingle
0x00020000
。在二进制文件中,这映射到:
bitsDecimal
因此,在第一种情况下,96位整数除以10的附加因子,而第二位16到23则给出值3而不是2.但是它被96位整数偏移本身,在第一种情况下也是第二种情况的10倍(显而易见的是第一种元素的价值)。
因此,观察值的差异可以归结为这样一个事实:bitsSingle 00000000 00000011 00000000 00000000
|\-----/ \------/ \---------------/
| | | |
sign <-+ unused exponent unused
| | | |
|/-----\ /------\ /---------------\
bitsDecimal 00000000 00000010 00000000 00000000
NOTE: exponent represents multiplication by negative power of 10
的转换使用了与“直”构造函数相比的微妙不同的逻辑来推导内部表示。