- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
frexpl
将不起作用,因为它将尾数保留为 long double 的一部分。我可以使用类型双关吗,否则会有危险吗?还有别的办法吗?
最佳答案
x86 的 float 和整数字节序是小端字节序,因此有效数(也称为尾数)是 80 位 x87 long double
的低 64 位。
在汇编中,您只需以正常方式加载,如mov rax, [rdi]
。
与 IEEE binary32 (float
) 或 binary64 (double
) 不同,80 位长 double 将前导 1 显式 存储在有效位中。 (或 0
表示次正规)。 https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format
因此,真正的有效数字的无符号整数值(大小)与实际存储在对象表示中的值相同。
如果你想要签名的int
,太糟糕了;包括符号位在内它将是 65 位,但 int
在任何 x86 C 实现上都只是 32 位。
如果你想要 int64_t
,你可以右移 1 以丢弃低位,为符号位腾出空间。如果设置了符号位,则执行 2 的补码取反,留下有效数值除以 2 的带符号 2 的补码表示。(IEEE FP 使用符号/幅度,位模式顶部有一个符号位)
在 C/C++ 中,是的,您需要输入双关语,例如使用 union 或 memcpy
。 x86/x86-64 上所有暴露 80 位浮点的 C 实现都使用 12 或 16 字节类型,底部有 10 字节值。
请注意 MSVC 使用 long double
= double
,一个 64 位 float ,所以检查 LDBL_MANT_DIG
来自 float.h
,或 sizeof(long double)
。所有 3 个 static_assert()
语句都在 MSVC 上触发,所以它们都完成了它们的工作并避免我们将整个 binary64 double
(sign/exp/mantissa) 复制到我们的 uint64_t
.
// valid C11 and C++11
#include <float.h> // float numeric-limit macros
#include <stdint.h>
#include <assert.h> // C11 static assert
#include <string.h> // memcpy
// inline
uint64_t ldbl_mant(long double x)
{
// we can assume CHAR_BIT = 8 when targeting x86, unless you care about DeathStation 9000 implementations.
static_assert( sizeof(long double) >= 10, "x87 long double must be >= 10 bytes" );
static_assert( LDBL_MANT_DIG == 64, "x87 long double significand must be 64 bits" );
uint64_t retval;
memcpy(&retval, &x, sizeof(retval));
static_assert( sizeof(retval) < sizeof(x), "uint64_t should be strictly smaller than long double" ); // sanity check for wrong types
return retval;
}
这compiles efficiently on gcc/clang/ICC (on Godbolt)仅将一条指令作为独立函数(因为调用约定在内存中传递 long double
)。在 x87 寄存器中使用 long double
内联代码后,它可能会编译为 TBYTE x87 存储和整数重新加载。
## gcc/clang/ICC -O3 for x86-64
ldbl_mant:
mov rax, QWORD PTR [rsp+8]
ret
对于 32 位,gcc 有一个奇怪的冗余复制错过优化错误,而 ICC 和 clang 没有;他们只是从函数 arg 执行 2 次加载,而不先复制。
# GCC -m32 -O3 copies for no reason
ldbl_mant:
sub esp, 28
fld TBYTE PTR [esp+32] # load the stack arg
fstp TBYTE PTR [esp] # store a local
mov eax, DWORD PTR [esp]
mov edx, DWORD PTR [esp+4] # return uint64_t in edx:eax
add esp, 28
ret
C99 使 union 类型双关成为明确定义的行为,GNU C++ 也是如此。我认为 MSVC 也定义了它。
但是 memcpy
总是可移植的,所以这可能是一个更好的选择,而且在我们只需要一个元素的情况下它更容易阅读。
如果您还需要指数和符号位,结构和 long double
之间的 union 可能会很好,只是在结构末尾填充对齐会使它更大。不过,在 uint16_t
成员之前的 uint64_t
成员之后不太可能有填充。但我担心 :1
和 :15
位域,因为 IIRC 是实现定义的,位域成员的存储顺序。
关于c - 如何在 x86-64 上将 80 位 long double 的尾数作为 int 获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57499986/
我知道这在 Linux 上是可能的。我尝试使用 open("E:", 0); 和 open("E:\\", 0); 但它返回为 -1。我想将 DVD 作为一个大文件来读取,而不是将其用作文件系统。 最
我正在尝试编译一个包含 CUDA 代码的小型库。 我已成功将其编译为共享库,但我真正需要的是静态库。 我有两个源文件: main.c:包含一个用C编写的测试函数。我用gcc编译这个文件 mai
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我正在使用 MingW 在 Windows 上编写 C 程序,并希望使用 EXPAT XML 库。我想静态编译我的程序,所以我需要静态 .a 库。 有什么方法可以将 EXPAT 编译成 Windows
我想将结果限制为 KEY_HOMEID 等于 journalId 的结果。我已经研究了几天,如有任何帮助,我们将不胜感激。 public Cursor fetchAllNotes(String jou
我一直在寻找这个信息,但是由于可以通过 homebrew 和 pip 安装额外的包和 python 版本,我感觉我的环境很乱向上。此外,很久以前,我用 sudo pip install 和 sudo
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我正在尝试合并目录中的所有 *.pdf : gswin64c -q -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=Total_Files.pdf -dBATCH *
所以我有一个简单的图像缩略图着陆页,例如: 在我的网站上,4 个并排显示在桌面上。如何强制它们在移动设备 View 中成对出现在一行中? 所以:桌面: #### 手机: ## ## 最佳答案
我正在使用 Ubuntu 21.04。我已删除 /usr/bin/python3和 /usr/lib/python3/因为某些软件包在二进制文件中出现错误。我的意思是重新安装python3到一个新的状
是否可以在 Windows 上使用 gyp 将 googles v8 构建为共享库(msvc 2012)?我试过的一切都不起作用。我试过的: python build\gyp_v8 -Dcompone
我需要将 rubygems 从 1.3.5 更新到 1.4.2 但显然 rubygems update 只是将您更新到最新版本 如何更新到 1.4.2? 最佳答案 您可以使用 RVM 安装特定
我还没有找到太多关于它的信息,但我看到了一些提示,表明可以在 iPhone 应用程序中使用 NSTask。如果可能的话,我将如何去做? 我不想越狱我的 iPhone,但我正在开发的应用程序仅供内部使用
我在 UIWebView 中有一个 map 图像。它默认加载在左上角。我希望它在 UIWebView 的中心初始化。 有人知道怎么做吗? 谢谢! 最佳答案 如果 map 图像是页面中唯一的内容,它是否
如何公开 NodePort 类型的服务上网没有 使用类型 LoadBalancer ?我发现的每个资源都是通过使用负载均衡器来完成的。但我不希望负载平衡对我的用例来说既昂贵又不必要,因为我正在运行 p
是否可以将 View 变成可编辑的,例如 this image ? 我知道我可以使用 GridView 来做到这一点。但是,我正在尝试使用 TableRows 来做到这一点,这可能吗? 编辑:我真正想
假设我已将 Heroku 应用程序扩展为 1 个工作进程,但如何指定具有特定名称的 rake 任务应作为工作进程运行? 最佳答案 在你的项目中创建一个 Procfile,然后像这样将 rake 任务放
目前,我在 GitHub 上一个项目的 README.md 文件中使用此 Markdown 文本: See the docs of [testthat][3] on how to write unit
我正在尝试使用一些到 uint8_t 的转换将 IPv4 转换为 IPv6。我知道 IPv4 有 4 个字节,IPv6 有 2 个字节的 16 个无符号整数,但我找不到它们转换的方法。 #includ
我是编程新手,目前正在学习 C。您能帮我解决以下案例吗? 一个例子是,如果用户输入“cbamike”,我想将其分成两个字符串:cba 和 mike。 我尝试了下面的代码,但它不起作用: #includ
我是一名优秀的程序员,十分优秀!