当前位置: 首页 > 知识库问答 >
问题:

如何使用printf打印单精度浮点

权黎昕
2023-03-14

我试图在x86_64汇编中打印一个浮点数,但它只是将值打印为零。

关于这一点已经有几个问题了。一个问题似乎通过确保您设置在%al中使用的向量寄存器的数量得到了解决。另一个表明您需要16个字节的堆栈对齐。但是,我正在做这两件事,但仍然没有得到正确的输出。

这是我的程序:

# prints a floating point value
.section .rodata
.fmt: .string "num: %f\n"
.num: .float 123.4

.section .text
.global main
.type   main, @function
main:
  subq $8, %rsp     # 16-byte alignment

  # print my number
  movss .num, %xmm0 # load float value
  movq $.fmt, %rdi  # load format string
  movb $1, %al      # use 1 vector register
  call printf

  # exit
  addq $8, %rsp     # undo alignment
  movq $0, %rax     # return 0
  ret

共有1个答案

甄阿苏
2023-03-14

printf(3)'s%f格式说明符需要一个双精度
无法让printf接受浮点,只能接受双精度或长双精度。

C的默认参数提升指定对可变函数的调用,如foo(char*fmt,...)浮点数提升到双精度,并执行窄整数类型的常规整数提升到int,用于跟踪与原型的...部分匹配的args。(这同样适用于调用没有原型的函数的所有args。)N15706.5.2.2函数调用,第6和7小节。

因此,C不能让调用方将浮点传递给printf,因此它没有转换%f表示双%lf也适用于现代printf实现中的C99/C11和C11。您可以安全地将相同的格式字符串与双精度字符串一起用于printf和scanf。

请注意,scanf是不同的。浮点数*双*不受这些促销活动的影响,因此您实际上可以使用%f扫描到浮点数

如果您查看编译器输出,您将看到gcc完成了您所做的一切。它像往常一样使用RIP相对寻址进行静态存储。

GCC还使用pxor首先将寄存器归零,以打破对%xmm0旧值的错误依赖。(cvtss2sd的糟糕设计使目标的64位上限保持不变。)GCC犯了谨慎的错误,并在许多情况下插入异或归零指令来打破错误依赖。

您可能会得到0,因为xmm0的高位恰好为零。当printf将xmm0的低64位视为(IEEE binary64 on x86)时,它会在尾数的低32位中找到123.4f的位模式,其余为零。作为64位,此位模式表示一个非常小的(低于正常的)数字,因此它以%f显示为零。

您可以尝试使用浮点值的等效值(例如http://www.h-schmidt.net/FloatConverter/IEEE754.html),在下半部分设置一些位以查看得到的结果。

如果使用%g(科学记数法)或%a(双位模式的十六进制表示),则会显示非零位。(除非在MXCSR中启用了非规范化为零模式,尽管glibc在转换为10进制字符串时可能使用纯整数来区分浮点位模式;这是一个困难的问题。)

 类似资料:
  • 我正在编写一个程序,打印浮点文字,以便在另一个程序中使用。 我需要打印多少位数才能保持原始浮点数的精度? 由于浮点数有十进制数字的精度,我最初的想法是打印8位数字应该足够了。但是,如果我运气不好,那会分布在7位有效数字的左侧和右侧,所以我应该打印9位十进制数字。 我的分析正确吗?9位十进制数字对所有情况都足够吗?如

  • 我正在尝试使用Java中的函数设置输出格式。 输出格式如下所示: 在每行输出中,应该有两列:第一列包含字符串,并使用完全字符左对齐。第二列包含整数,以数字表示;如果原始输入少于三位数,则必须用零填充输出的前导数字。 Java·       100 cpp         065 python     050 =============================================

  • 我试图改变一个数字在df,但熊猫转换为楼层号码。 我换了一个号码: 它给出: 而不是:

  • 有人能解释一下printf中的是如何使用说明符“%g”的吗?下面的输出让我很困惑: 我了解到使用最短的表示形式。 但是下面的输出仍然让我困惑 我的问题是:为什么能给出确切的数字,而不能? 似乎16个有效数字是准确的。有人能告诉我原因吗?

  • 问题内容: 我正在为一个学校项目创建一个RPN计算器。我在使用模运算符时遇到了麻烦。由于我们使用的是double数据类型,因此模数不适用于浮点数。例如,0.5%0.3应该返回0.2,但是我得到除以零的异常。 该指令说要使用fmod()。我到处都在寻找fmod(),包括javadocs,但找不到。我开始认为这是我必须创建的方法? 编辑:嗯,奇怪。我只是再次插入这些数字,它似乎工作正常……但以防万一。