浮点类型深谈

 

标题:浮点类型深谈

1.编写本文目的
浮点运算已属常用,但仍有深究必要,以消除其中可能的错误使用。

2.预期读者

3.编者语
㈠ 在其他任何公共论坛上转载本文,请标明出处和作者,而无需授权和确认。

4.正文
㈠ float格式简谈
Inter 80386/80387 及以上型号CPU有三种浮点类型,即短实数、长实数和80位临时实数,分别占用4字节、8字节和10字节,对应着C/C++中的float、double和long double[注1],我以 Real4、Real8和Real0表示之。
每种浮点格式皆应符合IEEE标准,称为规格化数,不符合IEEE标准的浮点格式称为非格式化数(NAN),我以最简单的float格式举例。
Float格式数据长32 bits,最高位为符号位:0为正,1为负;紧接着的8位为阶码:为了便于比较大小,其固定偏移7FH长,即0实际表示-7FH,7FH实际表示0,0FFH实际表示80H;余下的低23位为尾数(有效数字),为了使有效数字达到最大精度,这23个有效数字隐含着固定位1[注2],比如尾数10000000000000000000001其实就是1.10000000000000000000001,1被省略,而小数点固定在首位。
根据以上规则可以知道float所能表示的绝对值大小范围是
0 000,0000,0 000,0000,0000,0000,0000,0000 B 至
0 111,1111,1 111,1111,1111,1111,1111,1111 B
即±1.00000000000000000000000B×2(0x00-0x7F) 到±1.11111111111111111111111B×2(0xFF-0x7F)
然而事实上并不是这样,因为从这个范围可以看出它并不能表示0.0,而0.0为常用数字,所以特别规定±1.00000000000000000000000B×200为零,规定指数为0xFF的数字为非法数字,因此float实际的绝对值范围(除去0以外)是
0 000,0000,0 000,0000,0000,0000,0000,0001 B 至
0 111,1111,0 111,1111,1111,1111,1111,1111 B
即 0 并上 ±1.00000000000000000000001B×2(0x00-0x7F) 到±1.11111111111111111111111B×2(0xFE-0x7F)
可能的格式状态:
+不支持
+非有效数
-不支持
-非有效数
+规格化
+∞
-规格化
-∞
+0
+空
-0
-空
+不能规格化
-不能规格化
可能的异常:
无效操作
上溢
下溢
除零
不可规格化操作数
精度不足
㈡ 注意事项
a. 可以看出0可以用+0表示,也可以用-0表示,为此,CPU在比较零值时作了特殊处理,结果是±0虽然在存储器上格式不同,但比较值相同,然而如果是用字节来比较float类型大小时却需要注意这一点。
b. 运算上溢的值不是实际值,而是特值 0 111,1111,0 000,0000,0000,0000,0000,0000 B,例如 1.0×2127 + 1.5×2127 不等于 1.5×2128,虽然它有能力表示1.5×2128
c.
㈢ 在C++中的部分解决方案及遗留问题

5.参考资料
《Inter 80X86/80387 汇编指南》

6.附录
[注1]:M$认为double精度已足够,故在MVC++5.0及以后取消80位了临时实数,令long double等同于double,但在本文中的long double还是指80位临时实数。
[注2]:各种浮点类型格式类似,double指数偏移基数3FFH,long double指数偏移基数3FFFH,但long double特殊在无有效数字隐含位。
real04:符号位1,阶码08(固定偏移  7F),尾数23,固定隐含位有;
real08:符号位1,阶码11(固定偏移 3FF),尾数52,固定隐含位有;
real10:符号位1,阶码15(固定偏移3FFF),尾数64,固定隐含位无;

### 瀚高数据库中浮点类型的使用与定义 瀚高数据库(HighGo Database)基于 PostgreSQL 开发,因此其对于浮点类型的处理方式继承自 PostgreSQL 的设计[^1]。以下是关于瀚高数据库中浮点类型的具体使用和定义: #### 1. 浮点类型的基本定义 在 HighGo 数据库中,浮点类型主要包括 `REAL` 和 `DOUBLE PRECISION` 两种。这两种类型用于表示近似数值型数据。 - **REAL**: 占用 4 字节存储空间,提供大约 6 位十进制精度。 - **DOUBLE PRECISION**: 占用 8 字节存储空间,提供大约 15 位十进制精度。 这些类型遵循 IEEE 标准的二进制浮点数表示法,属于非精确类型的数据存储形式[^2]。 #### 2. 常量配置中的浮点类型表达 在 HighGo 数据库中,可以通过特定语法来定义和操作浮点类型常量。例如,在支持常量配置的情况下,可以采用如下格式: ```sql ["id", "'hello'::varchar", "true", "2.5::real", "power(2,3)"] ``` 上述例子中,“2.5::real” 明确指定了一个 REAL 类型的浮点数常量。通过显式的类型转换 (`::`) 可以确保该值被解释为指定的浮点类型。 #### 3. 隐式转换行为分析 当涉及不同数据类型之间的隐式转换时,需要注意浮点类型的行为差异。例如,在 openGauss 或者类似的数据库系统中,存在以下测试案例的结果展示: ```sql SELECT CAST(CAST(0.5 AS FLOAT) AS INTEGER) c1, CAST(CAST(0.6 AS FLOAT) AS INTEGER) c2, CAST(CAST(1.5 AS FLOAT) AS INTEGER) c3, CAST(CAST(2.5 AS FLOAT) AS INTEGER) c4; -- 结果: c1=0, c2=1, c3=2, c4=2 ``` 这表明即使是从浮点类型向整数类型进行转换,也可能因具体实现细节的不同而导致不同的结果。由于 HighGo 继承了 PostgreSQL 的特性,其浮点类型也应符合标准定义下的非精确性质。 #### 4. DDL 定义中的应用 在创建表结构的过程中,可以通过 DDL (Data Definition Language) 来定义包含浮点类型的字段。基本语法规则如下所示[^3]: ```sql CREATE TABLE example_table ( id SERIAL PRIMARY KEY, value_real REAL, value_double DOUBLE PRECISION ); ``` 此示例展示了如何分别声明 `REAL` 和 `DOUBLE PRECISION` 类型的列。 #### 5. 日志记录中的格式化选项 如果需要进一步调试或者监控涉及到浮点运算的操作,则可以在 postgresql.conf 文件中调整日志输出格式以便更好地理解实际发生的计算过程[^5]。例如: ```plaintext log_line_prefix = '%m [%p]: ' ``` 尽管这一功能主要用于性能调优或错误排查,但对于深入研究浮点数的表现仍然具有一定的辅助作用。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值