Arduino溢出

时间:2013-10-08 22:54:53

标签: types arduino overflow

所以我关注this tutorial以熟悉Arduino。在课程结束时,作者试图通过让我编写一个能够将任何给定GB转换为KB的程序来测试我对基本数学运算,位和字节的概念以及如何使用适当类型的数据的理解。我认为这是一件容易的事。但我想错了。

所以这是我的原始代码:

long drive_gb = 100; //given number
long drive_kb;
void setup()
{
   Serial.begin(9600);

   Serial.print("Your HD is ");
   Serial.print(drive_gb);
   Serial.println(" GB large.");


   drive_kb = 1024*1024*drive_gb;

   Serial.print("It can store ");
   Serial.print(drive_kb);
   Serial.println(" Kilobytes!");

 }

 void loop()
 {
 }

但是当我查看我的串行监视器时,我得到了这个输出:

“你的HD是100 GB大。 它可以存储0 Kilobytes!“

然后我将我的代码修改为:

long drive_gb = 100;
 long drive_kb;
 long drive_mb;
 void setup()

 {
   Serial.begin(9600);

   Serial.print("Your HD is ");
   Serial.print(drive_gb);
   Serial.println(" GB large.");

   drive_mb = 1024*drive_gb;
   drive_kb = 1024*drive_mb;

   Serial.print("It can store ");
   Serial.print(drive_kb);
   Serial.println(" Kilobytes!");

 }

 void loop()
 {
 }

现在我得到正确的输出

“你的HD是100 GB大。 它可以存储104857600 Kilobytes! “

所以我的问题是:

  1. 第一个代码是否导致溢出情况?怎么样?
  2. 第一个代码与第二个代码在数学上有何不同?
  3. 谢谢!

3 个答案:

答案 0 :(得分:2)

要获得明确的答案,您可以列出编译器在第一个示例中生成的汇编代码。

我的猜测是X = 1024 * 1024 * Y;的代码没有考虑到存储结果所需的long以及生成的代码使用的事实。

尝试:X = 1024L * 1024L * Y;,看看你是否得到了正确答案。

答案 1 :(得分:1)

  • 1024*1024*drive_gb表示(1024*1024)*drive_gb,因为根据C标准,乘法是从左到右的关联。
  • 1024表示(int) 1024,因为十进制常量具有第一种可以适合它们的类型(int,long,unsigned long)。
  • 1024*1024是两个整数的乘积,结果也是一个整数。
  • 在Arduino平台上(实际上是AVR),整数是16位,因此上面的产品溢出。

只需编写

即可获得正确的结果
drive_kb = 1024*(1024*drive_gb);

答案 2 :(得分:0)

如果你想要使用溢出,建议使用诸如MAX_INT之类的常量(如果可用),或者依赖于更多系统特定的类型,例如uint32_t,它明确地显示可用的字节/位数。