Numbers Precision
In this guide, we will discuss the limits and precision of numbers in Vein. We will also cover some common pitfalls when working with floating-point numbers, such as precision errors.
Limits of Number Types
Different number types in Vein have different limits and precision characteristics. Here is a summary:
Integer Types
Signed Integers
- i8 (SByte): Range from
-128
to127
. - i16: Range from
-32768 to 32767
. - i32: Range from
-2_147_483_648 to 2_147_483_647
. - i64: Range from
-9_223_372_036_854_775_808 to 9_223_372_036_854_775_807
. - i128: Range from
-170_141_183_460_469_231_731_687_303_715_884_105_728 to 170_141_183_460_469_231_731_687_303_715_884_105_727
.
Unsigned Integers
- u8 (Byte): Range from
0 to 255
. - u16: Range from
0 to 65_535
. - u32: Range from
0 to 4_294_967_295
. - u64: Range from
0 to 18_446_744_073_709_551_615
. - u128: Range from
0 to 340_282_366_920_938_463_463_374_607_431_768_211_455
.
Floating-Point Types
- f16 (Half): Approximate range from
6.10e-5 to 6.55e4
, with 3-4 decimal digits of precision. - f32 (Float): Approximate range from
1.18e-38 to 3.40e38
, with 6-7 decimal digits of precision. - f64 (Double): Approximate range from
2.23e-308 to 1.79e308
, with 15-16 decimal digits of precision. - f128 (Decimal): Approximate range from
1.0e-6145 to 7.9e6145
, with 33-34 decimal digits of precision.
Attention!
Currently i8 (signed byte), u128, i128, u256, i256, u512, i512, f128, f256 number is not implemented
Common Pitfalls with Floating-Point Arithmetic
Floating-point numbers are an approximation and thus can lead to precision errors. A well-known example of this is:
auto a: f64 = 0.1;
auto b: f64 = 0.2;
auto sum: f64 = a + b;
Out.println(sum == 0.3); // Output: false
Out.println(sum); // Output: 0.30000000000000004
Why Does This Happen?
The precision error occurs because floating-point numbers are represented in binary, and many decimal fractions (like 0.1 and 0.2) cannot be represented exactly in binary.
As a result, small errors accumulate, leading to unexpected behavior.
How to Mitigate Precision Errors
Use Decimal for Financial Calculations: When dealing with financial calculations or other applications that require high precision, consider using
f128 (Decimal)
.Rounding: Explicitly round numbers to a fixed number of decimal places if exact precision is required for comparisons.
auto a: f64 = 0.1;
auto b: f64 = 0.2;
auto sum: f64 = a + b;
auto isEqual: bool = (Math.round(sum * 1e10) / 1e10) == 0.3;
Out.println(isEqual); // Output: true
Attention!
Currently decimal floating point number is not implemented fully
- Tolerance for Comparisons: Use a small tolerance value for equality comparisons.
auto tolerance: f64 = 1e-10;
auto isEqual: bool = Math.abs(sum - 0.3) < tolerance;
Out.println(isEqual); // Output: true
Conclusion
Understanding the limits of different numeric types and the inherent precision issues with floating-point arithmetic is crucial for writing robust programs. Always consider these factors when designing algorithms that involve numeric computations.