<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="bbPress/1.0.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>LeafLabs Garden &#187; Topic: uint64 polarity problem</title>
		<link>http://forums.leaflabs.com/topic.php?id=1524</link>
		<description>A place to share, learn, and grow...</description>
		<language>en-US</language>
		<pubDate>Fri, 22 Jan 2016 00:18:17 +0000</pubDate>
		<generator>http://bbpress.org/?v=1.0.2</generator>
		<textInput>
			<title><![CDATA[Search]]></title>
			<description><![CDATA[Search all topics from these forums.]]></description>
			<name>q</name>
			<link>http://forums.leaflabs.com/search.php</link>
		</textInput>
		<atom:link href="http://forums.leaflabs.com/rss.php?topic=1524" rel="self" type="application/rss+xml" />

		<item>
			<title>gbulmer on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10119</link>
			<pubDate>Fri, 06 Apr 2012 13:07:02 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">10119@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;samtal - I would have written the code I posted, and been puzzled too, so I was pleased to learn.&#60;br /&#62;
Thanks for finding such a good question :-)&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;My understanding is that because I did not specify the number as unsigned, the compiler defaulted to signed int (or long-long).
&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;Yes, &#60;code&#62;int&#60;/code&#62; which is signed. I would bet money that that wasn't the case in K&#38;amp;R UNIX BSD C.&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;Then, because the high number was assumed to be signed and negative (msb=1), the byte became also signed, and negative (also, msb=1).
&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;It is the fact that constant is a &#60;code&#62;signed int&#60;/code&#62; that causes the first half of the problem. That is a problem waiting to happen.&#60;br /&#62;
The &#60;code&#62;int&#60;/code&#62; constant is wider than the &#60;code&#62;unsigned char&#60;/code&#62;, so the &#60;code&#62;unsigned char&#60;/code&#62; needs to be converted (widened), and that is to an &#60;code&#62;int&#60;/code&#62;. AFAIK C99 widens to &#60;code&#62;int&#60;/code&#62;. I assume it wasn't adequately specified before C99 (or they needed to change C to keep lots of &#60;em&#62;con&#60;/em&#62;sultants in work - sorry being a bit cynical).&#60;br /&#62;
The &#60;code&#62;unsigned char&#60;/code&#62; is multiplied or shifted (both fail) to an (signed) &#60;code&#62;int&#60;/code&#62;. Then the (signed) &#60;code&#62;int&#60;/code&#62; (which has its msb=1) is 'widened' to &#60;code&#62;unsigned long long&#60;/code&#62;.&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;1. How come two negative numbers gave a negative product?
&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;What are the two negative numbers? I think the only one is in_command[[].&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;2. What happened to the byte? did it lose its msb to the sign bit?
&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;when it was multiplied, yes its top bit became the sign bit of an int.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>samtal on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10118</link>
			<pubDate>Fri, 06 Apr 2012 09:51:19 +0000</pubDate>
			<dc:creator>samtal</dc:creator>
			<guid isPermaLink="false">10118@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Thanks gbulmer,&#60;br /&#62;
You had to dig quite deep to get all that info. Chapeau.&#60;br /&#62;
No doubt that left shift is better than multiplication (and probably significantly faster).&#60;br /&#62;
Originally, this is what I had, but then when I started to get problems I changes to multiplication, and was left there. I will change it back and see if it will become cleaner.&#60;br /&#62;
Regarding your comments:&#60;br /&#62;
My understanding is that because I did not specify the number as unsigned, the compiler defaulted to signed int (or long-long).&#60;br /&#62;
Then, because the high number was assumed to be signed and negative (msb=1), the byte became also signed, and negative (also, msb=1).&#60;br /&#62;
Question:&#60;br /&#62;
1. How come two negative numbers gave a negative product?&#60;br /&#62;
2. What happened to the byte? did it lose its msb to the sign bit? &#60;/p&#62;
&#60;p&#62;Well, it can become quite complex.&#60;br /&#62;
I'll juts make sure it works for me, and be more careful next time.&#60;br /&#62;
I'll keep the securecoding link. It is important.&#60;br /&#62;
I hope others will gain some knowledge of our work (mainly yours...)&#60;br /&#62;
samtal
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10109</link>
			<pubDate>Fri, 06 Apr 2012 03:23:37 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">10109@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;C/C++ integer operations are always carried out as if the two types were the same.&#60;/p&#62;
&#60;p&#62;According to these, conversions preserve the bits, but not signed-ness (since C99):&#60;br /&#62;
&#60;a href=&#34;https://www.securecoding.cert.org/confluence/display/seccode/INT02-C.+Understand+integer+conversion+rules&#34; rel=&#34;nofollow&#34;&#62;https://www.securecoding.cert.org/confluence/display/seccode/INT02-C.+Understand+integer+conversion+rules&#60;/a&#62;&#60;br /&#62;
&#60;a href=&#34;http://msdn.microsoft.com/en-us/library/fc9te331%28v=vs.80%29.aspx&#34; rel=&#34;nofollow&#34;&#62;http://msdn.microsoft.com/en-us/library/fc9te331%28v=vs.80%29.aspx&#60;/a&#62; &#60;/p&#62;
&#60;p&#62;The first one at securecoding.cert.org has an example &#34;Noncompliant Code Example&#34; involving 'port' which has some of similarity with the problem code.&#60;/p&#62;
&#60;p&#62;when &#60;code&#62;0x1000000&#60;/code&#62; is an &#60;code&#62;int&#60;/code&#62; then operation &#60;code&#62;in_command[1] * 0x1000000&#60;/code&#62; will give &#60;code&#62;int&#60;/code&#62;.&#60;br /&#62;
Then the &#60;code&#62;int&#60;/code&#62; is converted to &#60;code&#62;uint64&#60;/code&#62; for the &#60;code&#62;datetime + (in_command[1] * 0x1000000);&#60;/code&#62;&#60;/p&#62;
&#60;p&#62;So writing &#60;code&#62;0x1000000&#60;/code&#62; as &#60;code&#62;0x1000000u&#60;/code&#62; will cause the expression &#60;code&#62;in_command[1] * 0x1000000&#60;/code&#62; to be &#60;code&#62;unsigned int&#60;/code&#62;, so there will be no sign propagation.&#60;/p&#62;
&#60;p&#62;Similarly explicity casting will also ensure nothing becomes signed &#60;code&#62;(unsigned long long)in_command[1] * 0x1000000&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;The most explicit &#60;code&#62;(unsigned long long)in_command[1] * 0x1000000u&#60;/code&#62; is better.&#60;/p&#62;
&#60;p&#62;If you added this code to your program:&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;void show_inputs()
{
    Serial1.println();
    datetime =  (uint64)in_command[0] &#38;lt;&#38;lt; 32;
    Serial1.print(&#38;quot;datetime=&#38;quot;); Serial1.println(datetime, HEX);
    datetime = ((in_command[1]) &#38;lt;&#38;lt; 24);
    Serial1.print(&#38;quot;datetime=(uint64)&#38;quot;); Serial1.println(datetime, HEX);
    datetime = (unsigned int)((in_command[1]) &#38;lt;&#38;lt; 24);
    Serial1.print(&#38;quot;datetime=(unsigned int)&#38;quot;); Serial1.println(datetime, HEX);
    datetime = (uint64)((in_command[1]) &#38;lt;&#38;lt; 24);
    Serial1.print(&#38;quot;datetime=(no cast)&#38;quot;); Serial1.println(datetime, HEX);
    datetime = in_command[2] &#38;lt;&#38;lt; 16;
    Serial1.print(&#38;quot;datetime=&#38;quot;); Serial1.println(datetime, HEX);
    datetime = in_command[3] &#38;lt;&#38;lt; 8;
    Serial1.print(&#38;quot;datetime=&#38;quot;); Serial1.println(datetime, HEX);
    datetime = in_command[4];
    Serial1.print(&#38;quot;datetime=&#38;quot;); Serial1.println(datetime, HEX);

}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;and ran it, hopefully the problem would be clearer.&#60;br /&#62;
(There should be a warning from &#60;code&#62;datetime =  in_command[0] &#38;lt;&#38;lt; 32;&#60;/code&#62;)&#60;/p&#62;
&#60;p&#62;EDIT: This is the output (on my Mac):&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;datetime=8000000000
datetime=(uint64)FFFFFFFF81000000
datetime=(unsigned int)81000000
datetime=(no cast)FFFFFFFF81000000
datetime=820000
datetime=8300
datetime=84&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Summary: integer literals will be interpreted as signed unless explicitly written as unsigned. Since C99, integer conversions will not lose bits, but might loose signed-ness.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>samtal on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10096</link>
			<pubDate>Thu, 05 Apr 2012 15:23:04 +0000</pubDate>
			<dc:creator>samtal</dc:creator>
			<guid isPermaLink="false">10096@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;gbulmer,&#60;/p&#62;
&#60;p&#62;I run your code on IDE12, Maple-r5. Changed the print to HEX.&#60;br /&#62;
I did not add the ULL, and got good result as follows:&#60;/p&#62;
&#60;p&#62;datetime=1400000000&#60;br /&#62;
datetime=1401000000&#60;br /&#62;
datetime=1401020000&#60;br /&#62;
datetime=1401020300&#60;br /&#62;
datetime=1401020304&#60;/p&#62;
&#60;p&#62;When I changed the array inputs to 0x80, 0x81, 0x82, 0x83, 0x84 (msb=1),&#60;br /&#62;
I got the same error I had: (The second element is smaller than the first due to negative second element)&#60;/p&#62;
&#60;p&#62;datetime=8000000000&#60;br /&#62;
datetime=7F81000000&#60;br /&#62;
datetime=7F81820000&#60;br /&#62;
datetime=7F81828300&#60;br /&#62;
datetime=7F81828384&#60;/p&#62;
&#60;p&#62;I then added the ULL to the first two elements, then it was OK:&#60;/p&#62;
&#60;p&#62;datetime=8000000000&#60;br /&#62;
datetime=8081000000&#60;br /&#62;
datetime=8081820000&#60;br /&#62;
datetime=8081828300&#60;br /&#62;
datetime=8081828384&#60;/p&#62;
&#60;p&#62;As I wrote, although is seems to work, I do not understand why the array byte makes the difference rather than only the multiplier sign.&#60;/p&#62;
&#60;p&#62;thanks and let me know what your conclusions are.&#60;br /&#62;
samtal
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10095</link>
			<pubDate>Thu, 05 Apr 2012 14:11:40 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">10095@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;samtal - When you get time, would you run my program with your initialised values in &#60;code&#62;in_command[]&#60;/code&#62;, then post that program and output?&#60;br /&#62;
It might indicate a bug in &#60;code&#62;Serial1.println(unsigned long long)&#60;/code&#62;
&#60;/p&#62;</description>
		</item>
		<item>
			<title>samtal on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10094</link>
			<pubDate>Thu, 05 Apr 2012 13:45:56 +0000</pubDate>
			<dc:creator>samtal</dc:creator>
			<guid isPermaLink="false">10094@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Thanks gbulmer for a very very thorough and full reply.&#60;br /&#62;
The problem was solved by adding the ULL.&#60;br /&#62;
I simply overlooked the fact that the compiler relates to a constant as a signed integer, unless casted.&#60;br /&#62;
This also explains why I did not get the same problem with the small multipliers.&#60;/p&#62;
&#60;p&#62;It still does not explain why this depended on the array byte's sign, which is supposed to be unsigned.&#60;br /&#62;
I also changed the array byte type to uint8 which is 100% unsigned, but still, the outcome depended on the multiplier, unless casted by ULL.&#60;br /&#62;
I run all my test on the actual Maple5 board.&#60;/p&#62;
&#60;p&#62;I can now continue my work (hopefully) until the next time...&#60;/p&#62;
&#60;p&#62;Thanks again.&#60;br /&#62;
samtal
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10092</link>
			<pubDate>Thu, 05 Apr 2012 12:30:17 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">10092@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;samtal - the value in the pastebin code is &#60;strong&#62;0x100000000&#60;/strong&#62; which is too big to fit into an unsigned int.&#60;br /&#62;
By default, unsigned values are unsigned int, so the literal value should be stored as 0.&#60;br /&#62;
The top 1 is trimmed off. (The compiler should give a warning, but I haven't checked).&#60;/p&#62;
&#60;p&#62;Try writing it as 0x100000000ULL&#60;br /&#62;
I am not yet convinced that is enough to explain everything, but it is a start.&#60;/p&#62;
&#60;p&#62;The example program is significantly bigger than a minimal example.&#60;br /&#62;
It should initialise everything, so that there is no need to read input data; it is more robust to initialise than type input.&#60;br /&#62;
There is no example of what is printed, so it is not possible to confirm the same thing is output when run on my machine.&#60;/p&#62;
&#60;p&#62;Here is something closer to a minimal example. It fully specifies the expected values by throwing away all of the input reading. You should initialise &#60;code&#62;in_command&#60;/code&#62; with the actual values used, and republish. Then we can be confident we are testing the same thing.&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;#include &#38;quot;stdlib.h&#38;quot;

byte op_code;
byte in_command[20] = {
    0x14, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
    0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13
};

byte in_command_length;
uint64 datetime;

void setup()
{
    Serial1.begin(38400);
}

void loop()
{
    sort_inputs();
    delay(1000);
}

void sort_inputs()
{
    //Reconstruct the datetime variable by combining the 5 bytes as uint64

    Serial1.println();
    datetime =  in_command[0] * 0x100000000;  /* ERROR should be 0x100000000ULL */
    Serial1.print(&#38;quot;datetime=&#38;quot;); Serial1.println(datetime);
    datetime += in_command[1] * 0x1000000;
    Serial1.print(&#38;quot;datetime=&#38;quot;); Serial1.println(datetime);
    datetime += in_command[2] * 0x10000;
    Serial1.print(&#38;quot;datetime=&#38;quot;); Serial1.println(datetime);
    datetime += in_command[3] * 0x100;
    Serial1.print(&#38;quot;datetime=&#38;quot;); Serial1.println(datetime);
    datetime += in_command[4];
    Serial1.print(&#38;quot;datetime=&#38;quot;); Serial1.println(datetime);
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;I've run this on my Mac, which also defaults to 32-bit ints, and the results are not negative.&#60;br /&#62;
It will not compile because 0x100000000 is too big to fit into an int. When that is changed to 0x100000000ULL&#60;/p&#62;
&#60;p&#62;The output is:&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;datetime=85899345920
datetime=85916123136
datetime=85916254208
datetime=85916254976
datetime=85916254980&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Which looks plausible.&#60;/p&#62;
&#60;p&#62;I changed it to output in hex, and it is (still on my Mac):&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;datetime=1400000000
datetime=1401000000
datetime=1401020000
datetime=1401020300
datetime=1401020304&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Which looks correct to me. There are only 10 hex digits, which is 40-bits, so nothing is negative.&#60;br /&#62;
Unless the number is printed as 64bits long (which it is not) and the MSB is 1 (which would make the number hex 8 to F), then it just means that bit is set.&#60;/p&#62;
&#60;p&#62;Please paste your output so that we can inspect it. (Preferably print hex as that is easier to check.)&#60;/p&#62;
&#60;p&#62;One other possibility: &#60;code&#62;Serial1.println(unsigned long long)&#60;/code&#62; has a bug.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>samtal on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10090</link>
			<pubDate>Thu, 05 Apr 2012 11:40:18 +0000</pubDate>
			<dc:creator>samtal</dc:creator>
			<guid isPermaLink="false">10090@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Thanks juzza_s,&#60;/p&#62;
&#60;p&#62;I have built a minimum code that shows the problem.&#60;br /&#62;
code at: &#60;a href=&#34;http://pastebin.com/NF4jCuU8&#34; rel=&#34;nofollow&#34;&#62;http://pastebin.com/NF4jCuU8&#60;/a&#62;&#60;br /&#62;
What I am doing:&#60;br /&#62;
I have built a maple real-time clock.&#60;br /&#62;
To set the clock, I use a windows NT program that sends out via RS232 a reduced time stamp of 5 bytes (preceded by 02, length byte, ending with 03).&#60;br /&#62;
Example of sent data : 02 05 1E 87 0F AF 22 03&#60;br /&#62;
My program reads the bytes, fills in a byte array and then builds a time stamp of one uint64 value.&#60;/p&#62;
&#60;p&#62;The attached code, when run, shows that if, for example, I will make the second data byte &#38;gt; 0x80, the total value will be reduced because the byte conversion will be negative.&#60;/p&#62;
&#60;p&#62;As this has occupies too much of my time, I think if there is no solution I will find an easier way to set the RTC time, but I still want to understand what is wrong, thus any help will be appreciated, especially if there is a solution.&#60;br /&#62;
samtal.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>juzza_s on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10088</link>
			<pubDate>Thu, 05 Apr 2012 10:20:49 +0000</pubDate>
			<dc:creator>juzza_s</dc:creator>
			<guid isPermaLink="false">10088@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Can I see some of the code? To have a look at how you're casting and printing?
&#60;/p&#62;</description>
		</item>
		<item>
			<title>samtal on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10087</link>
			<pubDate>Thu, 05 Apr 2012 06:50:43 +0000</pubDate>
			<dc:creator>samtal</dc:creator>
			<guid isPermaLink="false">10087@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Thanks, but the problem is not only in printing, it is also in math calculations, where it counts as a negative rather than positive.&#60;br /&#62;
I have also tried casting to uint64 each appearance of the number, but for no avail.&#60;/p&#62;
&#60;p&#62;Any idea?
&#60;/p&#62;</description>
		</item>
		<item>
			<title>juzza_s on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10086</link>
			<pubDate>Thu, 05 Apr 2012 05:58:44 +0000</pubDate>
			<dc:creator>juzza_s</dc:creator>
			<guid isPermaLink="false">10086@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;How are you displaying the value?&#60;/p&#62;
&#60;p&#62;You could be printing the value out as a signed value where the MSB would produce a negative when printed.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>samtal on "uint64 polarity problem"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1524#post-10085</link>
			<pubDate>Thu, 05 Apr 2012 04:58:11 +0000</pubDate>
			<dc:creator>samtal</dc:creator>
			<guid isPermaLink="false">10085@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hi,&#60;br /&#62;
I have a number defined as type uint64 (or unsigned long long).&#60;br /&#62;
The number is built out of a byte multiplied by 0x1000000.&#60;br /&#62;
Yet, whenever the byte &#38;gt; 0x80 which makes the resulting msb equals 1, I get a negative value.&#60;br /&#62;
uint64 is not supposed to go negative. It is a simple 64 bits positive integer.&#60;/p&#62;
&#60;p&#62;Did anyone encounter similar situation, or have a reasonable explanation to this? &#60;/p&#62;
&#60;p&#62;Thanks&#60;br /&#62;
samtal
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
