C : 打印大数字 [英] C : Printing big numbers

查看:36
本文介绍了C : 打印大数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

采取以下措施:

#include <stdio.h>

main() {
    unsigned long long verybig = 285212672;

    printf("Without variable : %llu\n", 285212672);
    printf("With variable    : %llu", verybig);
}

这是上面程序的输出:

Without variable : 18035667472744448
With variable    : 285212672

<小时>

从上面可以看出,当 printf 将数字作为常量传递时,它会打印一些巨大的错误数字,但是当该值首先存储在变量中时,printf 打印正确的数字.


As you can see from the above, when printf is passed the number as a constant, it prints some huge incorrect number, but when the value is first stored in a variable, printf prints the correct number.

这背后的原因是什么?

推荐答案

Try 285212672ULL;如果不带后缀编写它,您会发现编译器将其视为常规整数.它在变量中工作的原因是因为整数在赋值中被转换为 unsigned long long,因此传递给 printf() 的值是正确的类型.

Try 285212672ULL; if you write it without suffixes, you'll find the compiler treats it as a regular integer. The reason it's working in a variable is because the integer is being cast up to an unsigned long long in the assignment, so that the value passed to printf() is the right type.

在你问之前,不,编译器可能不够聪明到无法从 printf() 中的 "%llu" 中找出来 格式字符串.这是不同层次的抽象.编译器负责语言语法,printf() 语义不是语法的一部分,它是一个运行时库函数(与您自己的函数没有什么不同,只是它是包含在标准中).

And before you ask, no, the compiler probably isn't smart enough to figure it out from the "%llu" in the printf() format string. That's a different level of abstraction. The compiler is responsible for the language syntax, printf() semantics are not part of the syntax, it's a runtime library function (no different really from your own functions except that it's included in the standard).

考虑以下 32 位 int 和 64 位 unsigned long long 系统的代码:

Consider the following code for a 32-bit int and 64-bit unsigned long long system:

#include <stdio.h>

int main (void) {
    printf ("%llu\n",1,2);
    printf ("%llu\n",1ULL,2);
    return 0;
}

输出:

8589934593
1

在第一种情况下,两个 32 位整数 1 和 2 被压入堆栈,printf() 将其解释为单个 64 位 ULL 值,2 x 232 + 1. 2 参数无意中包含在 ULL 值中.

In the first case, the two 32-bit integers 1 and 2 are pushed on the stack and printf() interprets that as a single 64-bit ULL value, 2 x 232 + 1. The 2 argument is being inadvertently included in the ULL value.

在第二个中,您实际上推送了 64 位 1 值和一个多余的 32 位整数 2,它被忽略了.

In the second, you actually push the 64-bit 1-value and a superfluous 32-bit integer 2, which is ignored.

请注意,格式字符串和实际参数之间的这种失步"是一个坏主意.类似的东西:

Note that this "getting out of step" between your format string and your actual arguments is a bad idea. Something like:

printf ("%llu %s %d\n", 0, "hello", 0);

很可能会崩溃,因为 %llu 会消耗 32 位 "hello" 指针,%s 会尝试取消引用最终的 0 参数.下面的图片"说明了这一点(假设单元格为 32 位,并且hello"字符串存储在 0xbf000000.

is likely to crash because the 32-bit "hello" pointer will be consumed by the %llu and %s will try to de-reference the final 0 argument. The following "picture" illustrates this (let's assume that cells are 32-bits and that the "hello" string is stored at 0xbf000000.

What you pass     Stack frames     What printf() uses
                 +------------+
0                | 0          | \
                 +------------+  > 64-bit value for %llu.
"hello"          | 0xbf000000 | /
                 +------------+
0                | 0          |    value for %s (likely core dump here).
                 +------------+
                 | ?          |    value for %d (could be anything).
                 +------------+

这篇关于C : 打印大数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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