我编写了一个小函数来将MB转换为Bytes,但是,int64中似乎存在一个错误。根据文档,int64的范围从-9223372036854775808到9223372036854775807,但我的结果不同......很多:
Const FreeSpace = 67100;
var FreeSpaceConverted :int64;
.
.
.
FreeSpaceConverted := FreeSpace shl 20;
对FreeSpace使用值67100会导致值为1639972864而不是70359449600.很明显,转换空间不足并且已经无处可寻。 int64的实际大小似乎是70359449600 - 1639972864 = 68719476736 = 2 ^ 36,而它应该是2 ^ 63-1。 36的指数看起来很奇怪。它可能是编译器本身的数字扭曲吗?
此外,使用以下替代方法会出现错误“转换或算术运算中的溢出”,即使它不应该:
FreeSpaceConverted := FreeSpace * 1024 * 1024;
另一方面,以下替代方案确实有效:
FreeSpaceConverted := FreeSpace * 1024;
FreeSpaceConverted := FreeSpaceConverted * 1024;
这是正常的行为,如果是这样,这是什么原因?
答案 0 :(得分:12)
您在问题中包含的所有代码在Delphi 7中都能正常运行。
program Int64Test;
{$APPTYPE CONSOLE}
var
FreeSpaceConverted, FreeSpace: Int64;
begin
FreeSpace := 67100;
FreeSpaceConverted := FreeSpace shl 20;
Writeln(FreeSpaceConverted);
FreeSpaceConverted := FreeSpace * 1024 * 1024;
Writeln(FreeSpaceConverted);
Readln;
end.
<强>输出强>
70359449600
70359449600
您的实际代码与您在问题中所述的不同。实际上,FreeSpace
在代码中声明为32位类型,可能是Integer
。例如,我不得不在这里猜一点:
program Int64Test;
{$APPTYPE CONSOLE}
var
FreeSpace: Integer;
FreeSpaceConverted: Int64;
begin
FreeSpace := 67100;
FreeSpaceConverted := FreeSpace shl 20;
Writeln(FreeSpaceConverted);
FreeSpaceConverted := FreeSpace * 1024 * 1024;
Writeln(FreeSpaceConverted);
Readln;
end.
<强>输出强>
1639972864
1639972864
如果我们启用溢出检查,则在您报告时,乘法代码会导致溢出异常。
当FreeSpace shl 20
是整数时,现在考虑FreeSpace
。编译器将其解释为32位整数运算,并将更高有效位移出32位寄存器的末尾。您分配给64位整数的事实是不相关的。重要的是表达式中的数据类型。您可以通过在右侧包含强制转换为Int64
来使代码按您希望的方式运行。
program Int64Test;
{$APPTYPE CONSOLE}
var
FreeSpace: Integer;
FreeSpaceConverted: Int64;
begin
FreeSpace := 67100;
FreeSpaceConverted := Int64(FreeSpace) shl 20;
Writeln(FreeSpaceConverted);
FreeSpaceConverted := Int64(FreeSpace) * 1024 * 1024;
Writeln(FreeSpaceConverted);
Readln;
end.
<强>输出强>
70359449600
70359449600
为了进行更全面的讨论,我建议您Barry Kelly's answer to another question。
答案 1 :(得分:2)
我没碰巧在这个系统上安装D7,但我确实有Delphi 2007,其中,这段代码:
var
FreeSpaceConverted, FreeSpace:int64;
begin
try
FreeSpace := 67100;
FreeSpaceConverted := FreeSpace shl 20;
writeln(FreeSpaceConverted);
readln;
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.
收益率“70359449600”。
答案 2 :(得分:0)
我正在使用Delphi XE7。我认为问题在于将32位整数转换为64位整数。如果我使用你的代码,我会做同样的事情。但是,如果我首先将FreeSpace强制转换为int64,即
Const FreeSpace:int64 = 67100;
我得到了正确的结果。
答案 3 :(得分:-1)
好的,所以这条线不起作用 - &GT; FreeSpaceConverted:= FreeSpace shl 20;
也许你应该看这部分 - &GT; FreeSpace shl 20;
是的,FreeSpace shl 20,你可能想看看这个 - &GT;常量 - &GT; FreeSpace = 67100;
也许D7认为FreeSpace为Integer 32常量? 如果是这样,您可能希望将代码更改为此类代码 - &GT;常量 - &GT; FreeSpace:Int64 = 67100;
这里不需要无类型常量,除非你想做这样的事情 VAR 答:整数的数组[0..FreeSpace] 除此之外,你不需要无类型的常量。
更多信息 在Pascal中,无类型常量就像文本编辑器的替代品。您可以在使用数字的地方使用无类型常量。 它不需要任何内存引用,它只是一个文本编辑器替换。你无法进行任何操作 例: 常量 答:整数= 10; B = 20;
开始 公司(A); // 有用 公司(B); //不仅它不起作用,还会产生编译错误 端;
比较
无类型常量类型常量
C #define A 20 long a = 20;
Pascal const A = 20; const A:整数= 20;
装配A等于20 A dd 20;双字,整数32
;装配中的等价物