铸造所做的是将一件事转换为另一件事。它可能是 8 位整数到 16 位或 32 位
unsigned int x;
unsigned char y;
y = 7;
x = (unsigned int) y;
如果你做了 x=y; 这当然是暗示的。假设这里有 8 位和 32 位类型定义。从位模式 0x07 到 0x00000007。
这实际上是一个非常有趣的练习。让我们组成一个格式,然后思考问题。
浮点格式通常会做这样的事情,我们可以纯粹以正数来思考并完成大部分练习。以 10 为底的数字 1234,我们在小学谈论科学记数法,即 1.234 乘以 10 的 3 次方。基于两种计算机格式的工作方式相同,之所以称为浮点数是有原因的。小数在虚拟意义上移动。因此,浮点数中的数字 9 0b1001 你会想要找到最重要的一个,然后将小数放在它之后 1.001 乘以 2 的 3 次幂。数字 17 是 1.0001 乘以 2 的 4 次幂。浮点必须覆盖符号,它“分数”或尾数必须有一些位,因为即使是整数,我们也要强制分数。然后是指数。我们不一定需要保留可以在某些格式中假定的小数点之前的那个。当然,零是一个特殊问题,浮点格式需要一个特殊的异常或模式。该格式还需要一些位数来表示所应用的 2 的幂。对于初学者,我们假设只生成正整数,我们的整数是 8 位,所以 0 到 0xFF 是我们整个整数世界。我们的双精度格式有 12 个小数位,我们的单精度格式有 5 个以供争论。对于初学者,我们假设只生成正整数,我们的整数是 8 位,所以 0 到 0xFF 是我们整个整数世界。我们的双精度格式有 12 个小数位,我们的单精度格式有 5 个以供争论。对于初学者,我们假设只生成正整数,我们的整数是 8 位,所以 0 到 0xFF 是我们整个整数世界。我们的双精度格式有 12 个小数位,我们的单精度格式有 5 个以供争论。
那么我们最坏情况下的数字 0xFF 是多少,我们可以用 12 个小数位 1.111111100000 乘以 2 的 7 次方轻松表示,并假设我们的格式有足够多的指数位来涵盖整个练习。
所以我们的 double 可以保存我们的每一个整数,在 C
dx = 双(x);
只是意味着转换格式,如果我们从位模式 00001001 开始,它是数字 9,在我们的双倍中,这将是 1.001000000000 乘以 2 的幂 3 幂是我们以我们的格式存储的更多位,但与这个问题无关.
在我们组合的单曲中,数字 9 是 1.00100 乘以 2 的 3 次方。
但是我们单精度中的数字 0xFF 是 1.11111 乘以 2 的 7 次方,当我们将其转换回整数时,它是 0xFC 而不是 0xFF,我们在转换中丢失了一些位。假设没有四舍五入。以 10 1/27 为底数是 0.0307307307 ...如果我们将其截断为 4 位数,我们将得到 0.0307,这有点低。但是如果我们取 3 0.031 并四舍五入,那就有点太高了。如果我们看一下单曲中的 0xFF,它是 1.11111,接下来被扔掉的两位是 11,这是一半以上,所以如果我们将 10.00000 乘以 2 的 7 次归一化为 1.00000 乘以 2 的 8 次方怎么办。0xFF 基本上舍入到 0x100。我们可以用 0x100 代表 0xff 或 0xFC 代表 0xFF 有点高或有点低但不准确,当我们转换回来时,我们要么有点高要么有点低。
所以看看第一种情况 A (float)x vs (float)((double)x) 1.00100 乘以 2 的幂 3 vs 1.001000000000 乘以 2 的幂 3. 覆盖 float x vs double x 然后必须转换双精度,浮点格式之间使用的剪裁和舍入是否与整数浮动相同?取决于硬件,但人们希望 11111111 转换与 1.111111100000 相同,但也许它不会,在理想的世界中它会。
C 是一个有趣的例子,会这样说,表示一个两位数加上一个两位数需要多少位?正数 最坏情况 3 + 3 = 6 多少位扩大 0xFF 加上 0xFF 现在很多位在我们的双格式中是否超过 12?取 0xFF 加上 0xFF 加上 0xFF 这需要多少位?是不是超过 12 个?重新安排分组会改变吗?
D 两位数 3*3 = 9 每个操作数的两位输入多少位?0xFF 乘以 0xFF?那么 0xFF 乘以 0xFF 乘以 0xFF 是否需要超过 12 位?是第一个问题。第二个问题如果是这样,那么裁剪和舍入如何工作?剪裁和舍入是否受分组影响。那是迄今为止的脑筋急转弯,我可能必须编写一个简单的程序才能理解它。
而且E并不像我最初想的那么讨厌,重新阅读它。我将位模式与确切的位模式分开。除法的最大问题是什么,不仅是计算机,而且一般来说,什么整数给我们带来了问题并解决了其他问题?如果我们在这里允许有符号数正x除以正x和负z除以负z怎么办?
所以在维基百科搜索双精度浮点然后搜索单精度。double 有多少个“分数”位?并假设一个 32 位或 31 和一个 int 的符号,所有有效数字都适合吗?考虑正数,我们将有 2 到 31 的幂现在需要许多指数位来表示数字 31?是否有足够?那么,你可以在分数中保存 31 或 30 个有效位吗?你能用指数表示正负 31 的幂吗?
编辑
于是想着案例DI写了一个程序。我使用了 8 位小数
//5 9 f 020140 030120 0301E0 090151 090152
(5 * 9) * 15 vs 5 * (9 * 15)
所以 5 是 1.01000000 或 0x1.40,9 是 1.00100000 或 0x1.20,0xF 是 1.11100000 或 0x1.E0。
float 中的乘法与您想象的不一样,这会让您的大脑有些受伤,因为我们不是直接将 5 乘以 9,而是将所有内容都移动了,因此它是 1.something 所以它是
0x120 * 0x140 = 0x16800
由于标准化,你砍掉了 8 位,这就是我们将看到的四舍五入的地方,在这种情况下,结果是 0x168,不需要标准化
5*9 = 0x2D = 101101
1.01101000 0x1.68
我不需要关心指数,但他们只是加 5 的指数为 2,9 的指数为 8,所以结果是 0x168,指数为 5 所以 0x168 乘以 0x1E0 = 0x2A300 由于性质,我们立即切断 8 位 0x2A3的乘法。现在我们标准化我们需要 1.soemthing 而不是 2.something 所以我们向右移动并增加指数所以指数是 5+3=8 我们再给它一个 9 但注意到一些东西 0x2A3 0x1010100011 我们要丢掉一点精度而不是 0x1.51 半位,我们有 0x1.51 基数 2 浮点的性质。现在这应该是为了总结答案吗?也许。如果是这样,那么答案 0x1.52
Take it the other way 5*(9*15)
0x120*0x1E0 = 0x21C00
or 0x21C 1000011100
0x10E
0x140*0x10E = 0x15180
we are going to lose a bit here
is it 0x151 or 0x152?
这些是等效的四舍五入问题吗?两条路径是否导致 0x152 使它们相等,或者是一种截断位的视图与另一种不同?如果我们根本不四舍五入,只剪辑两个答案都是 0x152。
3 11 1f 010180 040110 0401F0 0A018B 0A018A
(3*17)*31 vs 3*(17*31) no rounding just clipping
(3*17)*31
0x180*0x110 = 0x19800
0x198
0x198*0x1F0 = 0x31680 0x316 0x1100010110
0x18B
3*(17*31)
0x110*0x1F0 = 0x20f00
0x107
0x180*0x107 = 0x18A80
0x18A
0x18B != 0x18A
一条路径我们剪掉了两位,另一条路径只有一条。那公平吗?0x31680 作为一个整体
110001011010000000
110001011 010000000 with discarded bits on the right
因此,以这种方式看,01 或 010 或 0100 不到一半,不超过 3 或 2 的四舍五入 1.33 不会以 10 为基数四舍五入到 1.4。
但是 0x20F00
100000111100000000
100000111 100000000
就在中间点 1/10, 10/100, 100/1000 是一半。
那应该是0x108吗?
0x180*0x108 = 0x18C00
0x18C
0x18C != 0x18B
所以以这种方式查看舍入,它仍然不匹配排序产生了影响。
也许你认为我做错了舍入,这是公平的,如果是这样,这是否会使所有可能的整数模式都起作用?假设 int 是 32 位,double 是 IEEE754 和 52 位尾数,我们将溢出它并且必须砍掉位,因此会发生斩波和舍入,排序重要吗?