了解printf的隐式转换 [英] Understanding implicit conversions for printf

查看:137
本文介绍了了解printf的隐式转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C99标准区分隐式和显式类型转换(6.3转换).我猜,但没有找到,当目标类型比源精度更高时,可以执行隐式强制转换,并且可以表示其值. [这就是我认为从INT到DOUBLE会发生的事情.鉴于此,我看下面的示例:

The C99 Standard differentiate between implicit and explicit type conversions (6.3 Conversions). I guess, but could not found, that implicit casts are performed, when the target type is of greater precision than the source, and can represent its value. [That is what I consider to happen from INT to DOUBLE]. Given that, I look at the following example:

#include <stdio.h>  // printf
#include <limits.h> // for INT_MIN
#include <stdint.h> // for endianess
#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)

int main()
{
  printf("sizeof(int): %lu\n", sizeof(int));
  printf("sizeof(float): %lu\n", sizeof(float));
  printf("sizeof(double): %lu\n", sizeof(double));
  printf( IS_BIG_ENDIAN == 1 ? "Big" : "Little" ); printf( " Endian\n" );

  int a = INT_MIN;
  printf("INT_MIN: %i\n", a);
  printf("INT_MIN as double (or float?): %e\n", a);
}

我很惊讶地发现输出:

sizeof(int): 4
sizeof(float): 4
sizeof(double): 8
Little Endian
INT_MIN: -2147483648
INT_MIN as double (or float?): 6.916919e-323

因此,打印出的浮点值是接近极小次正规正双精度4.9406564584124654×10 ^ -324的次正规浮点数.当我注释掉两个printf的字节序时,会发生奇怪的事情,而double值又得到了另一个值:

So the float value printed is a subnormal floating point number near the very minimal subnormal positive double 4.9406564584124654 × 10^−324. Strange things happen when I comment out the two printf for endianess, I get another value for the double:

#include <stdio.h>  // printf
#include <limits.h> // for INT_MIN
#include <stdint.h> // for endianess
#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)

int main()
{
  printf("sizeof(int): %lu\n", sizeof(int));
  printf("sizeof(float): %lu\n", sizeof(float));
  printf("sizeof(double): %lu\n", sizeof(double));
  // printf( IS_BIG_ENDIAN == 1 ? "Big" : "Little" ); printf( " Endian\n" );

  int a = INT_MIN;
  printf("INT_MIN: %i\n", a);
  printf("INT_MIN as double (or float?): %e\n", a);
}

输出:

sizeof(int): 4
sizeof(float): 4
sizeof(double): 8
INT_MIN: -2147483648
INT_MIN as double (or float?): 4.940656e-324

  • gcc --version:(Ubuntu 4.8.2-19ubuntu1)4.8.2
  • uname:x86_64 GNU/Linux
  • 编译器选项,其中:gcc -o x x.c -Wall -Wextra -std = c99 --pedantic
  • 是的,那里有一个警告:
    • gcc --version: (Ubuntu 4.8.2-19ubuntu1) 4.8.2
    • uname: x86_64 GNU/Linux
    • compiler options where: gcc -o x x.c -Wall -Wextra -std=c99 --pedantic
    • And yes there where one warning:
    • x.c: In function ‘main’:
      x.c:15:3: warning: format ‘%e’ expects argument of type ‘double’, but argument 2
                has type ‘int’ [-Wformat=]
      
         printf("INT_MIN as double (or float?): %e\n", a);
         ^
      

      但是我仍然无法理解到底发生了什么.

      But I still cannot understand what exactly is happening.

      • 在小巧的情况下,我认为MIN_INT为:00 ... 0001,MIN_DBL(低于标准)为100..00#,从尾数开始,然后是指数,最后以#作为符号位.
      • li>
      • 这种在int上应用%e"格式说明符的形式是隐式强制转换还是重新解释强制转换?
      • in little endianess I consider MIN_INT as: 00...0001 and MIN_DBL (Subnormal) as 100..00#, starting with the mantissa, followed by the exponent and conclude with the # as sign bit.
      • Is this form of applying "%e" format specifier on an int, is a implicit cast?, a reinterpret cast?

      我迷路了,请赐教.

      推荐答案

      printf("INT_MIN as double (or float?): %e\n", a);
      

      上一行有问题您不能使用%e打印整数.该行为是不确定的.

      Above line has problem You can not use %e to print ints. The behavior is undefined.

      您应该使用

      printf("INT_MIN as double (or float?): %e\n", (double)a);
      

      double t = a;
      printf("INT_MIN as double (or float?): %e\n", t);
      

      相关文章:这篇文章解释了在printf中使用不正确的打印说明符可能会导致UB.

      Related post: This post explains how using incorrect print specifiers in printf can lead to UB.

      这篇关于了解printf的隐式转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆