【问题标题】:C programming Printing a float as long double in hexC编程以十六进制打印浮点数
【发布时间】:2019-04-07 13:46:44
【问题描述】:

我正在为家庭作业创建一个程序,目标是教我们如何从概念上了解工会的运作方式。我相信我理解这个概念,但我对我的一个输出有困难;十六进制的长双倍。

我假设任何东西在打印时都需要在百分号后加一个大写 L。例如打印一个长双浮点数:

printf("\nLong double: %Lf\n", value.ld);

同样,如果我想以十六进制打印 Long Double 浮点数,我会使用:

printf("\nLong double: %Lx", value.ld);

我教授的输出如下:

Professors Output 长双 22fde0

我的输出如下:

My Output 长双62fe40

Long Double 十六进制的打印值不同。这是一个可能因计算机而异的值还是我的想法有误。

我的代码

#include <stdio.h>

// define union data
    union data {
        float f;
        double d;
        long double ld;
    }value; //union variable

// begin main function
int main(void){

    // get initial user input
    printf("Enter data for type float: ");
    scanf(" %f", &value.f);

    puts("\nBreakdown of the element in the union: ");
    printf("Float: %f", value.f);
    printf("\nDouble: %f", value.d);
    printf("\nLong double: %Lf\n", value.ld);

    puts("\nBreakdown in hex: ");
    printf("Float: %x", value.f);
    printf("\nDouble: %x", value.d);
    printf("\nLong double: %Lx", value.ld);

    // get user input
    printf("\n\nEnter data for type double: ");
    scanf(" %lf", &value.d);

    puts("\nBreakdown of the element in the union: ");
    printf("Float: %f", value.f);
    printf("\nDouble: %f", value.d);
    printf("\nLong double: %Lf\n", value.ld);

    puts("\nBreakdown in hex: ");
    printf("Float: %x", value.f);
    printf("\nDouble: %x", value.d);
    printf("\nLong double: %Lx", value.ld);

    // get user input
    printf("\n\nEnter data for type long double: ");
    scanf(" %lf", &value.ld);

    puts("\nBreakdown of the element in the union: ");
    printf("Float: %f", value.f);
    printf("\nDouble: %f", value.d);
    printf("\nLong double: %Lf\n", value.ld);

    puts("\nBreakdown in hex: ");
    printf("Float: %x", value.f);
    printf("\nDouble: %x", value.d);
    printf("\nLong double: %Lx", value.ld);

    return 0;
} // end main function

【问题讨论】:

  • 你真的认为联合可以转换对象表示吗?在您的情况下,您似乎希望设置 union data 的浮动对象会神奇地为您提供以 doublelong double 格式表示的相同值?
  • @Frankie_C 不相信它应该是一样的,这就是这个任务的重点。我们最后存储到联合中的任何值都是其中保存的值。
  • “我们最后存储到联合中的值就是其中保存的值”这是正确的。那么分配一个浮点数并转储长双精度的十六进制内容应该是什么意思?从浮点初始化值打印双精度或长双精度也是无稽之谈...
  • @Frankie_C 表明输出对于我们刚刚扫描的内容以外的任何内容都不正确。您是说我们的输出不同是因为值一开始就不好吗?跨度>
  • @Frankie_C 谢谢,我想我明白了。感谢您的帮助

标签: c


【解决方案1】:

%x 格式说明符要求以十六进制打印整数类型。为此传入浮点类型会调用未定义的行为。

您可以使用 %a 格式说明符以十六进制打印浮点数:

printf("\nLong double: %La", value.ld);

【讨论】:

【解决方案2】:

这个值是否可能因计算机而异

当然。完全不清楚您的教授所说的“long double as hex”是什么意思。如果你照你做的那样,将long double 传递给%x 说明符,那么你会得到未定义的行为——%x 说明符需要一个整数(或变体),如果你想预测会发生什么并不容易传递一个浮点数(或变体)。

如果您使用%a 说明符,它明确用于以十六进制打印浮点数,那么您将获得浮点值的十六进制表示,而不是内存的内容。因此,例如1.5 将打印为0x1.8p+0,因为.8 是十六进制,而.5 是十进制。

如果您真正想要的是内存的内容,如十六进制,那么您需要将一个整数传递给%x 说明符。最简单的方法是向联合中添加适当的整数类型。

union data {
        float f;
        int i;
        double d;
        long int li;
        long double ld;
        long long int lli;
    }value; //union variable

然后,如果你想要一个双精度十六进制的内存内容,例如,只需使用:

// get user input
printf("\n\nEnter data for type double: ");
scanf(" %f", &value.d);

puts("\nBreakdown of the element in the union: ");
printf("Double: %f", value.d);
printf("Hex: %lx", value.li);

顺便说一句,%l...(小写 ell)用于整数,%L...(大写 ell)用于浮点类型。 long int 通常与 64 位平台上的 double 大小相同(但不能保证如此!)。 %f,有点令人困惑,是用于 double 参数。 floats 没有说明符 - 它们会自动提升为 doubles。

【讨论】:

    【解决方案3】:

    请使用union,正如how to print float in hex format in C?中所指出的那样

    这是我从链接中抓取的:

    #include <stdio.h>
    #include <stdint.h>
    #include <inttypes.h>
    #include <math.h>
    
    int main (void) {
    
        float pi = (float)M_PI;
        union {
            float f;
            uint32_t u;
        } f2u = { .f = pi };
    
        printf ("pi (floating point): %f\n", pi);
        printf ("pi (hex representation): 0x%\n", f2u.u);
    
        return 0;
    }
    

    输出:

    $ ./bin/float_hex
    pi (floating point) : 3.141593
    pi (hex representation): 0x40490fdb
    

    【讨论】:

    • 我很抱歉,但我在发表自己的帖子之前已经查看了这篇文章,并且我的问题没有得到那个帖子的回答。如果我使用 %a 或 %La ,则十六进制输出为 0x0.000000p-1022 ,这与我的 22fde0 教授相差甚远
    • 也许我的教授错了,因为我研究得越多,我就越相信输出应该是 0x0.000000p-1022 的格式
    • 这个答案不使用%a。它打印代表浮点数的四字节的十六进制格式 - 即 0x40490fdb 用于 3.141593 的 pi。
    猜你喜欢
    • 2021-07-07
    • 2018-10-07
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-14
    • 2021-05-04
    相关资源
    最近更新 更多