{"id":22,"date":"2009-01-09T00:19:56","date_gmt":"2009-01-09T00:19:56","guid":{"rendered":"http:\/\/www.sanchitkarve.com\/blog\/?p=22"},"modified":"2009-01-09T00:19:56","modified_gmt":"2009-01-09T00:19:56","slug":"consequences-of-data-type-range-violations","status":"publish","type":"post","link":"https:\/\/www.sanchitkarve.com\/blog\/2009\/01\/09\/consequences-of-data-type-range-violations\/","title":{"rendered":"Consequences of Data type Range Violations"},"content":{"rendered":"<p>I\u2019ve come across a lot of people who wonder why a number stored in a variable, if exceeds its range, turns into a weirder negative number.<br \/>\nTo explain this phenomena they offer a conclusion without showing any evidence and this conclusion is in no way close to the truth.<br \/>\nHere\u2019s what happens.<\/p>\n<p>The numbers change because of the complement notation that the computer uses to store negative numbers.<\/p>\n<p>And it\u2019s not the compiler\u2019s fault but the processor\u2019s limitation.<br \/>\nThis code will give negative numbers on 32-bit,16-bit and 8bit Microprocessors as each register can hold 32\/16\/8 bits respectively.<br \/>\nYou won\u2019t encounter this problem on 64-bit processors as each register can hold a maximum of 64-bits. (Actually, you will encounter the same problem since the value of INT_MAX will be a 64-bit number for a 64 bit processor\u2026.but it\u2019ll work fine with 32-bit numbers)<\/p>\n<p>Adding a Number to a maximum value set in these registers creates the problem.<br \/>\nHave a look at this printf statement (I\u2019ve typecasted it for portability)<\/p>\n<pre lang=\"cpp\">printf(\u201d%d = %xn%d = %x\u201d,INT_MAX,INT_MAX,(unsigned long)INT_MAX+1,(unsigned long)INT_MAX+1);<\/pre>\n<p>The compiler generates the following code:<\/p>\n<pre lang=\"asm\">push    10000000000000000000000000000000b\npush    10000000000000000000000000000000b\npush    1111111111111111111111111111111b\npush    1111111111111111111111111111111b\npush    offset aDXDX ; format\ncall    _printf\nadd     esp, 14\n\u2026\n\u2026\naDXDX  db \u2018%d = %x\u2019,0Ah\n       db \u2018%d = %x\u2019,0<\/pre>\n<p>Now, the values in the first 2 push Instructions is the binary representation of INT_MAX (2147483647 for 32-bit systems). Note that it is comprised of only ONE\u2019s.<\/p>\n<p>When 1 is added to INT_MAX, look what happens to the next two push instructions.<br \/>\nThis number is 2147483648 but in unsigned notation\u2026but in signed notation it\u2019s -2147483648 since the Most Significant Bit decides the Sign of a Number.<\/p>\n<p>And since by default the compiler assumes that a variable is signed, you get the negative value.<\/p>\n<p>Try the same C code after replacing %d with the %u format specifier.<br \/>\nYou\u2019ll notice that 2147483648 will be the output.<\/p>\n<p>Remember, there\u2019s nothing like postive or negative numbers\u2026It\u2019s all about interpretation. 111 (for a 3 bit architecture) could mean 7(without using MSB for sign-convention\u2026ie. unsigned) as well as -1 (using MSB for sign ie. signed).<\/p>\n<p>You might wonder why I\u2019ve blamed the Processor and not the compiler in spite of the fact that the Compiler has precalculated the result of addition and passed it to printf.<br \/>\nThe reason is that I\u2019ve compiled the above code in Aggressive Optimization, so the compiler generates push instructions.<br \/>\nNormally the Compiler plays safe and lets the processor take care of such values by generating the following code:<\/p>\n<pre lang=\"asm\">mov eax, 1111111111111111111111111111111b\nlea edx, [eax+1]\npush edx<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I\u2019ve come across a lot of people who wonder why a number stored in a variable, if exceeds its range, turns into a weirder negative number. To explain this phenomena they offer a conclusion without showing any evidence and this conclusion is in no way close to the truth. Here\u2019s what happens. The numbers change [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[7],"tags":[21,23,55],"_links":{"self":[{"href":"https:\/\/www.sanchitkarve.com\/blog\/wp-json\/wp\/v2\/posts\/22"}],"collection":[{"href":"https:\/\/www.sanchitkarve.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sanchitkarve.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sanchitkarve.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sanchitkarve.com\/blog\/wp-json\/wp\/v2\/comments?post=22"}],"version-history":[{"count":0,"href":"https:\/\/www.sanchitkarve.com\/blog\/wp-json\/wp\/v2\/posts\/22\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.sanchitkarve.com\/blog\/wp-json\/wp\/v2\/media?parent=22"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sanchitkarve.com\/blog\/wp-json\/wp\/v2\/categories?post=22"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sanchitkarve.com\/blog\/wp-json\/wp\/v2\/tags?post=22"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}