Я искал документы, но я не могу найти ничего, чтобы объяснить это.Почему переполнение приводит к 0?
У меня есть программа D:
import std.stdio;
void main() {
writeln(int.max);
int a = 2;
int b = 180;
writeln(a^^b);
}
Он пишет:
2147483647
0
Я переполнена int
, но вместо того, чтобы мусор или упаковку, я получаю 0
.
Если я использую real
или double
, очевидно, что результат будет правильным.
Я написал программу, чтобы экспериментировать с этим в C (не то, что C является D, а D компилируется в машинный код и C портативный ассемблер, поэтому они должны быть сопоставимы):
#include <stdio.h>
#include <math.h>
#include <limits.h>
int main(void) {
double i = pow(2, 128);
int j = (int) i;
printf("int max: %d\n", INT_MAX);
printf("print dbl as int: %d\n", i);
printf("cast dbl -> int: %d\n", j);
printf("double: %f\n", i);
return 0;
}
Это дает:
int max: 2147483647
print dbl as int: -1254064128
cast dbl -> int: -2147483648
double: 340282366920938463463374607431768211456.000000
Вторая и третья линии линия редко будет то же самое в два раза, так как я считаю, что это неопределенное поведение, которое является точкой.
Я знаю, что D хочет быть лучшим C, и способ сделать это - устранить неопределенное поведение.
Но если D является языком системного программирования (он даже имеет встроенный asm
), почему D отказывается от переполнения?
Просто примечание: точка двух строк C, которые являются неправильными, целенаправленно неопределенна/неверна, чтобы продемонстрировать результат, которого я ожидал. Но теперь я понимаю, так что спасибо. – cat
«он переинтерпретирует литье этих битов в int», в C это неопределенное поведение *. Результат (если есть) может не иметь сходства с входом, например. на общих 64-битных системах значения с плавающей запятой передаются в printf с использованием разных регистров, чем для целочисленных значений. –
Да, конечно, поэтому это так случайно! –