【发布时间】:2020-01-23 06:02:08
【问题描述】:
我一直在查看http://www.netlib.org/fdlibm/ 的一些代码以了解某些功能是如何工作的,并且我正在查看 e_log.c 的代码以及它的某些部分代码:
hx = __HI(x); /* high word of x */
lx = __LO(x); /* low word of x */
__HI(x) 和 __LO(x) 的代码是:
#define __HI(x) *(1+(int*)&x)
#define __LO(x) *(int*)&x
我真的不明白,因为我不熟悉这种类型的 C。有人可以向我解释一下 __HI(x) 和 __LO(x) 在做什么吗?
在函数的代码后面还有一条语句:
__HI(x) = hx|(i^0x3ff00000);
谁能给我解释一下:
- 如何使函数等于某物(我通常使用 python,所以我真的不知道发生了什么)?
-
__HI(x)和__LO(x)在做什么? - 程序中x的“高位字”和“低位字”是什么意思?
我分析的最终目的是理解这段代码,以便将其移植到 Python 实现中
【问题讨论】:
-
C 中的
#define name(args)实际上并不是一个函数,尽管在大多数情况下你可以像使用它一样使用它。#语句在编译时被预处理器读取,#define正在创建一个宏 en.wikipedia.org/wiki/… -
@RobertoCaboni 我有 64 位...
-
使用保留标识符会产生未定义的行为。以双下划线开头的标识符(如您的
__HI和__LOW)是保留的,因此使用它们会产生未定义的行为。 -
第二个原因是未定义的行为(除了使用@Peter 指出的保留标识符):它违反了严格的别名。这也是 horrible 代码,这取决于
int是特定大小(我猜是 32 位),并且架构是 little-endian。 Brrrr。 -
@Peter:这种行为不是“未定义的”,因为有问题的代码是 fdlibm 的一部分,它被设计为 C 实现的一部分,而不是普通 C 程序使用的源代码。因此,它不包含在 C 标准的规则中。 应该使用保留标识符,因为 C 标准保留标识符的部分目的是保留它们以供 C 实现使用,以便实现中使用的名称不会与使用的名称冲突在主题源代码中。