问题描述
我正尝试将52乘以1000,结果却是负数
int getNewSum = 52 * 1000;
,但是以下代码得出的结果是负数:-13536
二进制补码的解释在Wikipedia和其他地方提供的代表性作品可能要比这里更好.我在这里要做的是带您了解确切示例的工作原理.
您的Arduino上的int类型用16位表示,以2的补码表示(请记住,其他Arduino使用32位,但您使用16位.)这意味着正数和负数都可以是存储在这16位中,如果设置了最左边的位,则该数字被视为负数.
正在发生的事情是您溢出了可用于存储正数的位数,并且(偶然地,就您而言)设置了符号位,从而表明该数为负./p>
在Arduino的16位中,十进制52将以二进制表示为:
0000 0000 0011 0100
(2 ^ 5 + 2 ^ 4 + 2 ^ 2 = 52)
但是,将52乘以1,000-52,000的结果最终将溢出int的幅度位,最后在符号位上放置'1':
*----This is the sign bit. It's now 1, so the number is considered negative.
1100 1011 0010 0000
(通常,由于各种原因,计算机整数算术和关联的编程语言都无法保护您避免执行此类操作,主要是与效率有关,而现在则大多是历史原因.)
因为设置了左端的符号位,要将其数字从假定的二进制补码表示形式转换回十进制,我们假设它是一个负数,然后先取一个二进制补码(翻转所有位) :
0011 0100 1101 1111
-代表13,535-并向其添加一个,得出13,536,并将其称为负数:-13,536,即您所看到的值.
如果您通常阅读二进制的补码/整数表示法,那么您将一窍不通.
同时,这可能意味着您应该寻找一种更大的类型来存储您的电话号码. Arduino具有无符号整数,并且具有 long 类型,该类型将使用四个字节存储您的数字,从而您的范围是-2,147,483,648至2,147,483,647.如果您足够了,您可能应该切换为使用long
而不是int
.
I am trying to times 52 by 1000 and i am getting a negative result
int getNewSum = 52 * 1000;
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.
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.
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)
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
-- 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.
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算术错误否定结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!