Arduino 算术错误否定结果 [英] Arduino Arithmetic error negative result

查看:20
本文介绍了Arduino 算术错误否定结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将 52 乘以 1000,但结果是否定的

I am trying to times 52 by 1000 and i am getting a negative result

int getNewSum = 52 * 1000; 

但以下代码输出否定结果:-13536

but the following code is ouputting a negative result: -13536

推荐答案

二进制补码的解释 在维基百科和其他地方提供的代表作品可能比这里更好.我在这里要做的是带您了解具体示例的工作原理.

An explanation of how two's complement representation works is probably better given on Wikipedia and other places than here. What I'll do here is to take you through the workings of your exact example.

Arduino 上的 int 类型使用 16 位表示,以二进制补码表示(请记住,其他 Arduino 使用 32 位,但您使用的是 16 位.)这意味着正数和负数都可以存储在这 16 位中,如果设置了最左边的位,则该数字被认为是负数.

The int type on your Arduino is represented using sixteen bits, in a two's complement representation (bear in mind that other Arduinos use 32 bits for it, but yours is using 16.) This means that both positive and negative numbers can be stored in those 16 bits, and if the leftmost bit is set, the number is considered negative.

发生的事情是您溢出了可用于存储正数的位数,并且(就您而言,偶然地)设置了符号位,从而表明该数字为负数.

What's happening is that you're overflowing the number of bits you can use to store a positive number, and (accidentally, as far as you're concerned) setting the sign bit, thus indicating that the number is negative.

在 Arduino 上的 16 位中,十进制 52 将以二进制表示为:

In 16 bits on your Arduino, decimal 52 would be represented in binary as:

0000 0000 0011 0100

(2^5 + 2^4 + 2^2 = 52)

(2^5 + 2^4 + 2^2 = 52)

但是,将 52 乘以 1,000 -- 52,000 -- 的结果最终会溢出 int 的大小位,在末尾的符号位中放置一个1":

However, the result of multiplying 52 by 1,000 -- 52,000 -- will end up overflowing the magnitude bits of an int, putting a '1' in the sign bit on the end:

*----This is the sign bit. It's now 1, so the number is considered negative.
1100 1011 0010 0000

(通常,计算机整数算术和相关的编程语言并不能保护您免于做这样的事情,原因多种多样,主要与效率有关,而且现在大多是历史性的.)

(typically, computer integer arithmetic and associated programming languages don't protect you against doing things like this, for a variety of reasons, mostly related to efficiency, and mostly now historical.)

因为左端的符号位已设置,为了将该数字从其假定的二进制补码表示转换回十进制,我们假设它是一个负数,然后首先取其补码(翻转所有位):

Because that sign bit on the left-hand end is set, to convert that number back into decimal from its assumed two's complement representation, we assume it's a negative number, and then first take the one's complement (flipping all the bits):

0011 0100 1101 1111

-- 代表 13,535 -- 再加一,得到 13,536,并称其为负数:-13,536,您看到的值.

-- which represents 13,535 -- and add one to it, yielding 13,536, and call it negative: -13,536, the value you're seeing.

如果您阅读了一般的二进制补码/整数表示,您就会掌握它的窍门.

If you read up on two's complement/integer representations in general, you'll get the hang of it.

与此同时,这可能意味着您应该寻找更大的类型来存储您的号码.Arduino 具有无符号整数和 long 类型,它将使用四个字节来存储您的数字,给出你的范围从 -2,147,483,648 到 2,147,483,647.如果这对你来说足够了,你可能应该切换到使用 long 而不是 int.

In the meantime, this probably means you should be looking for a bigger type to store your number. Arduino has unsigned integers, and a long type, which will use four bytes to store your numbers, giving you a range from -2,147,483,648 to 2,147,483,647. If that's enough for you, you should probably just switch to use long instead of int.

这篇关于Arduino 算术错误否定结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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