Integer overflow: Difference between revisions

Content deleted Content added
Definition variations and ambiguity: running out of memory is not an example of integer overflow.
Bender the Bot (talk | contribs)
 
(4 intermediate revisions by 4 users not shown)
Line 2:
{{Use American English|date=January 2019}}
 
[[File:Odometer rollover.jpg|thumb|250pxupright=1.3|Integer overflow can be demonstrated through an [[odometer]] overflowing, a mechanical version of the phenomenon. All digits are set to the maximum 9 and the next increment of the white digit causes a cascade of carry-over additions setting all digits to 0, but there is no higher digit (1,000,000s digit) to change to a 1, so the counter resets to zero. This is ''wrapping'' in contrast to ''saturating''.]]
 
In [[computer programming]], an '''integer overflow''' occurs when an [[arithmetic]] operation on integers attempts to create a numeric value that is outside of the range that can be represented with a given number of digits – either higher than the maximum or lower than the minimum representable value.
 
Integer overflow specifies an overflow of the [[Data type|data type]] [[Integer (computer science)|integer]]. An overflow (of any type) occurs when a [[Computer program|computer program]] or system tries to store more data in a fixed-size ___location than it can handle, resulting in [[Data loss|data loss]] or [[Data corruption|corruption]].<ref>{{cite web|url=https://www.lenovo.com/us/en/glossary/overflow-error |title=What is an overflow error?}}</ref> The most common implementation of integers in modern computers are [[Two's complement|two's complement]].<ref>E.g. "Signed integers are two's complement binary values that can be used to represent both positive and negative integer values", Section 4.2.1 in ''Intel 64 and IA-32 Architectures Software Developer's Manual'', Volume 1: Basic Architecture, November 2006</ref> In two's complement the [[Bit numbering#Most_significant_bit|most significant bit]] represents the [[Sign bit|sign]] (positive or negative), and the remaining [[Bit numbering#Signed_integer_example|least significant bits]] represent the number. Unfortunately, for most [[Computer architecture|architectures]] the [[Arithmetic logic unit|ALU]] doesn't know the [[Binary number|binary representation]] is [[Signedness|signed]]. [[Two's_complement#Arithmetic_operations|Arithmetic operations]] can result in a value of bits exceeding the fixed-size of bits representing the number, this causes the sign bit to be changed, an integer overflow. The most infamouslyinfamous examples are: [[2,147,483,647#In_computing|2,147,483,647]] + 1 = -2,147,483,648 and [[32-bit computing#Range_for_storing_integers|-2,147,483,648]] - 1 = 2,147,483,647.
 
On some processors like [[graphics processing unit]]s (GPUs) and [[digital signal processor]]s (DSPs) which support [[saturation arithmetic]], overflowed results would be ''clamped'', i.e. set to the minimum value in the representable range if the result is below the minimum and set to the maximum value in the representable range if the result is above the maximum, rather than wrapped around.
Line 15:
 
== Origin ==
Integer overflow occurs when an [[arithmetic]] operation on integers attempts to create a numeric value that is outside of the range that can be represented with a given number of digits. In the context of computer programming, the integers are [[Binary numeral system|binary]], but any [[Positional notation|positional]] [[numeral system]] can have an invalid result of an arithmetic operation if positions are confined. As shown in the odometer example, using the [[Decimal|decimal]] system, with the constraint of 6 positions ([[Numerical digit|digits]]) the following operation will have an invalid result: {{math|999999 + 1}}. Likewise, a binary system limited to 4 positions ([[bit|bits]]) will have an invalid result for the following operation: {{code|1111 + 1}}. For both examples the results will have a value exceeding the range that can be represented by the constraints. Another way to look at this problem is that the [[Significant figures|most significant]] position's operation has a [[Carry (arithmetic)|carry]] requiring another position/digit/bit to be allocated, breaking the constraints.
 
All integers in computer programming have constraints of a max value and min value. The primary factors for determining the range is the allocation of bits and if it is [[Signedness|signed or unsigned]]. The [[Integer (computer science)#Standard_integer|standard integer]] depends on the [[Computing platform|platform]] and [[programming language]]. Additional integer representation can be less than or greater than standard. Examples are the [[Integer (computer science)#Short_integer|short integer]] and [[Integer (computer science)#Long_integer|long integer]] respectively. Even [[Arbitrary-precision arithmetic|arbitrary-precision]] exists, but would be limited by [[Arbitrary-precision arithmetic#Pre-set_precision|pre-set precision]] or available system memory.
 
Most [[Arithmetic logic unit|ALUs]] perform operations on [[Signedness|unsigned]] (positive) [[Binary number|binary numbers]]. These ALUs do not have any capability of dealing with [[Signedness|signed]] (positive and negative) numbers. Because most numbers in programs need to support negative numbers, an abstraction is used, redefining the bits' meaning to include a sign. The most common solution is [[Two's complement|two's complement]]. Most programming languages provide this construct. A signed 32-bit integer, will use the [[Bit numbering#Most_significant_bit|most significant bit]] to signify the [[Sign bit|sign]] (positive or negative), and the remaining [[Bit numbering#Signed_integer_example|31-bits]] to represent the number. When an [[Two's_complement#Arithmetic_operations|operation]] occurs that results in a [[Carry (arithmetic)|carry]] past the 31-bits allocated for the number, the sign bit is overwritten. The ALU doesn't know it did anything wrong. It is up to the program to detect this overflow fault.
 
For usage of unsigned integers of [[register width]], the ALU is not capable of returning a result with more bits outside the it'sits width. The ALU will return the result along with a flag for carry-out. When these flags are returned true, the ALU has detected overflow.
 
After overflow is detected, it is up to the program to handle this with additional logic. The resulting value from the operation is [[Data corruption|corrupted]] and can cause additional issues if not handled properly.
 
Using integers of the same size as the [[Arithmetic logic unit|ALU]]'s [[register width]] will have the best performance in most applications. [[Single instruction, multiple data|SIMD]] [[Instruction set architecture|instruction]] extensions can provide single operations for integers exceeding the register width. For [[x86]] [[32-bit computing|32-bit processors]] the [[Streaming SIMD extensions]] (SSE2) added registers for 64-bit integers. For [[x86-64]] [[64-bit computing|64-bit processors]] the [[Advanced Vector Extensions]] (AVX) added registers up to 512-bit integers.<ref>{{cite web|url=https://www.intel.com/content/www/us/en/content-details/812656/intel-avx-512-fast-modular-multiplication-technique-technology-guide.html|title=Intel® AVX-512 - Fast Modular Multiplication Technique}}</ref>
Line 34:
|-
! rowspan="2" style="white-space: preserve nowrap; text-align:center;" | [[8-bit computing|8-bit]]
| rowspan="2" style="text-align:center;" | [[byte]]<ref name="byte">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.byte|title=.NET Byte Struct }}</ref>{{efn|name=byte}}, sbyte,<ref name="sbyte">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.sbyte|title=.NET SByte Struct }}</ref>, [[octet (computing)|octet]]
| rowspan="2" style="white-space: preserve nowrap; text-align:center;" | 2<sup>8</sup> − 1 || {{small|-128<ref name="sbyte.min">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.minvalue |title=.NET SByte.MinValue Field }}</ref>}} || {{small|0<ref name="byte.min">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.byte.minvalue |title=.NET Byte.MinValue Field }}</ref>}}
|-
Line 42:
|-
! rowspan="2" style="white-space: preserve nowrap; text-align:center;" | [[16-bit computing|16-bit]]
| rowspan="2" style="text-align:center;" | [[Word (data type)|word]], [[Integer (computer science)#Short_integer|short]], int16,<ref name="int16">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.int16|title=.NET Int16 Struct }}</ref>, uint16<ref name="uint16">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.uint16|title=.NET UInt16 Struct }}</ref>
| rowspan="2" style="white-space: preserve nowrap; text-align:center;" | 2<sup>16</sup> − 1 || {{small|−32,768<ref name="int16.min">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.int16.minvalue |title=.NET Int16.MinValue Field }}</ref>}} || {{small|0<ref name="uint16.min">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.uint16.minvalue |title=.NET UInt16.MinValue Field }}</ref>}}
|-
Line 50:
|-
! rowspan="2" style="white-space: preserve nowrap; text-align:center;" | [[32-bit computing|32-bit]]{{efn|name=common2005}}
| rowspan="2" style="white-space: preserve nowrap; text-align:center;" | int32,<ref name="int32">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.int32|title=.NET Int32 Struct }}</ref>, uint32<ref name="uint32">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.uint32|title=.NET UInt32 Struct }}</ref>
| rowspan="2" style="white-space: preserve nowrap; text-align:center;" | 2<sup>32</sup> − 1 || {{small|[[32-bit computing#Range_for_storing_integers|-2,147,483,648]]<ref name="int32.min">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.int32.minvalue |title=.NET Int32.MinValue Field }}</ref>}} || {{small|0<ref name="uint32.min">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.uint32.minvalue |title=.NET UInt32.MinValue Field }}</ref>}}
|-
Line 58:
|-
! rowspan="2" style="white-space: preserve nowrap; text-align:center;" | [[64-bit computing|64-bit]]{{efn|name=common2025}}
| rowspan="2" style="white-space: preserve nowrap; text-align:center;" | int64,<ref name="int64">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.int64|title=.NET Int64 Struct }}</ref>, uint64<ref name="uint64">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.uint64|title=.NET UInt64 Struct }}</ref>
| rowspan="2" style="white-space: preserve nowrap; text-align:center;" | 2<sup>64</sup> − 1 || {{small|−9,223,372,036,854,775,808<ref name="int64.min">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.int64.minvalue |title=.NET Int64.MinValue Field }}</ref>}} || {{small|0<ref name="uint64.min">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.uint64.minvalue |title=.NET UInt64.MinValue Field }}</ref>}}
|-
Line 70:
|-
! rowspan="2" style="white-space: preserve nowrap; text-align:center;" | [[128-bit computing|128-bit]]
| rowspan="2" style="white-space: preserve nowrap; text-align:center;" | int128,<ref name="int128">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.int128|title=.NET Int128 Struct }}</ref>, uint128<ref name="uint128">{{cite web |url=https://learn.microsoft.com/en-us/dotnet/api/system.uint128 |title=.NET UInt128 Struct }}</ref>
| rowspan="2" style="white-space: preserve nowrap; text-align:center;" | 2<sup>128</sup> − 1 || {{small|−170,141,183,460,469,231,731,687,303,715,884,105,728}} || {{small|0}}
|-
Line 138:
| [[Python (programming language)|Python]] 2 || {{N/A}} || convert to <var>long</var> type (bigint)
|-
| [[Seed7]] || {{N/A}} || <samp>'''raise''' OVERFLOW_ERROR</samp><ref>[httphttps://seed7.sourceforge.net/manual/errors.htm#OVERFLOW_ERROR Seed7 manual], section 16.3.3 OVERFLOW_ERROR.</ref>
|-
| [[Scheme (programming language)|Scheme]] || {{N/A}} || convert to bigNum