在我们讨论下一个主题之前,我们将侧重于科学记数法。
科学记数法是一种简洁书写长数字的有用速记方法。尽管科学记数法一开始可能看起来很陌生,但理解科学记数法将帮助您理解浮点数的工作原理,更重要的是,理解它们的局限性。
科学记数法中的数字采用以下形式:有效数字 x 10指数。例如,在科学记数法 1.2 x 10⁴
中,1.2
是有效数字,4
是指数。由于 10⁴ 等于 10,000,因此 1.2 x 10⁴ 等于 12,000。
按照惯例,科学记数法中的数字写成小数点前只有一位数字,其余数字在小数点后。
考虑地球的质量。在十进制记数法中,我们会将其写为 5972200000000000000000000 kg
。这是一个非常大的数字(甚至大到无法放入 8 字节整数中)。它也很难阅读(那是 19 个零还是 20 个零?)。即使使用分隔符(5,972,200,000,000,000,000,000,000),这个数字仍然难以阅读。
在科学记数法中,这将被写为 5.9722 x 10²⁴ kg
,这更容易阅读。科学记数法还有一个额外的好处,那就是通过比较指数,可以更容易地比较两个极大或极小数的量级。
因为在 C++ 中很难输入或显示指数,我们使用字母“e”(有时是“E”)来表示方程中“乘以 10 的幂”的部分。例如,1.2 x 10⁴
将被写为 1.2e4
,而 5.9722 x 10²⁴
将被写为 5.9722e24
。
对于小于 1 的数字,指数可以是负数。数字 5e-2
等效于 5 * 10⁻²
,即 5 / 10²
,或者 0.05
。电子的质量是 9.1093837e-31 kg
。
对于 Linux 用户
如果您使用的是 Arch Linux 并且 5 * 10⁻²
的上标缺少负号,您可能需要安装一个可以显示这些字符的字体。有关更多信息,请参阅此 Reddit 帖子。
有效数字
假设你需要知道数学常数 pi 的值用于某个方程,但你忘记了。你问两个人。一个人告诉你 pi 的值是 3.14
。另一个人告诉你 pi 的值是 3.14159
。这两个值都是“正确”的,但后者更精确。
这是关于科学记数法最重要的一点:有效数字('e' 之前的数字)被称为有效数字(或有效位数)。有效数字越多,数字就越精确。
关键见解
有效数字越多,数字就越精确。
在科学记数法中,我们会将 3.14
写成 3.14e0
。由于有效数字中有 3 个数字,因此这个数字有 3 个有效数字。
3.14159
将被写成 3.14159e0
。由于有效数字中有 6 个数字,因此这个数字有 6 个有效数字。
如何将十进制数转换为科学记数法
使用以下步骤:
- 您的指数从零开始。
- 如果数字没有明确的小数点(例如
123
),则它隐式地在最右端(例如123.
)。 - 将小数点向左或向右移动,以便小数点左侧只有一个非零数字。
- 每向左移动小数点一位,指数增加 1。
- 每向右移动小数点一位,指数减少 1。
- 去除所有前导零(有效数字的左端)
- 仅当原始数字没有小数点时,才去除所有尾随零(有效数字的右端)。我们假设它们不重要。如果您有额外信息表明它们很重要,您可以保留它们。
以下是一些示例:
Start with: 600.410 Slide decimal point left 2 spaces: 6.00410e2 No leading zeros to trim: 6.00410e2 Don't trim trailing zeros: 6.00410e2 (6 significant digits)
Start with: 0.0078900 Slide decimal point right 3 spaces: 0007.8900e-3 Trim leading zeros: 7.8900e-3 Don't trim trailing zeros: 7.8900e-3 (5 significant digits)
Start with: 42030 (no information to suggest the trailing zero is significant) Slide decimal point left 4 spaces: 4.2030e4 No leading zeros to trim: 4.2030e4 Trim trailing zeros: 4.203e4 (4 significant digits)
Start with: 42030 (assuming the trailing zero is significant) Slide decimal point left 4 spaces: 4.2030e4 No leading zeros to trim: 4.2030e4 Keep trailing zeros: 4.2030e4 (5 significant digits)
处理尾随零
考虑这样一种情况,我们请两位实验室助手分别称量同一个苹果。一位回来报告说苹果重 87.0 克。另一位回来报告说苹果重 87.000 克。假设称量是正确的。在前一种情况下,苹果的实际重量可能在 86.950 到 87.049 克之间。也许秤的精度只到小数点后一位。或者我们的助手稍微进行了四舍五入。在后一种情况下,我们对苹果的实际重量有更高的信心(它的实际重量在 86.99950 到 87.00049 克之间,这具有更小的变异性)。
转换为科学记数法时,小数点后的尾随零被认为是有效的,因此我们保留它们
- 87.0g = 8.70e1
- 87.000g = 8.7000e1
对于没有小数点的数字,尾随零默认被认为是无关紧要的。给定数字 2100(没有额外信息),我们假设尾随零不重要,因此我们将其去掉
- 2100 = 2.1e3(尾随零被认为不重要)
但是,如果我们碰巧知道这个数字是精确测量的(或者实际数字在 2099.5 到 2100.5 之间),那么我们应该将这些零视为有效数字
- 2100 = 2.100e3(尾随零已知有效)
提示
您偶尔会看到一个数字以明确的尾随小数点书写。这表明前面的零是有效的。
- 2100. = 2.100e3(尾随零已知有效)
科学记数法的一个优点是它总是清楚地表明有多少位有效数字。
从技术角度来看,数字 87.0 和 87.000 具有相同的值(和相同的类型)。当 C++ 将这些数字中的任何一个存储到内存中时,它将只存储值 87。一旦存储,就无法从存储的值中确定最初输入的是这两个数字中的哪一个。
现在我们已经讨论了科学记数法,我们准备讨论浮点数。
小测验时间
问题 #1
将以下数字转换为科学记数法(使用 e 表示指数),并确定每个数字有多少个有效数字。
记住,小数点后的尾随零要保留,没有小数点的尾随零要去除。
a) 34.50
b) 0.004000
c) 123.005
d) 146000
e) 146000.001
f) 0.0000000008
g) 34500.0
h) 146000(假设您知道零是有效的)