060_floats.zig 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. //
  2. // Zig has support for IEEE-754 floating-point numbers in these
  3. // specific sizes: f16, f32, f64, f80, and f128. Floating point
  4. // literals may be written in the same ways as integers but also
  5. // in scientific notation:
  6. //
  7. // const a1: f32 = 1200.0; // 1,200
  8. // const a2: f32 = 1.2e+3; // 1,200
  9. // const b1: f32 = -500_000.0; // -500,000
  10. // const b2: f32 = -5.0e+5; // -500,000
  11. //
  12. // Hex floats can't use the letter 'e' because that's a hex
  13. // digit, so we use a 'p' instead:
  14. //
  15. // const hex: f16 = 0x2A.F7p+3; // Wow, that's arcane!
  16. //
  17. // Be sure to use a float type that is large enough to store your
  18. // value (both in terms of significant digits and scale).
  19. // Rounding may or may not be okay, but numbers which are too
  20. // large or too small become inf or -inf (positive or negative
  21. // infinity)!
  22. //
  23. // const pi: f16 = 3.1415926535; // rounds to 3.140625
  24. // const av: f16 = 6.02214076e+23; // Avogadro's inf(inity)!
  25. //
  26. // A float literal has a decimal point. When performing math
  27. // operations with numeric literals, ensure the types match. Zig
  28. // does not perform unsafe type coercions behind your back:
  29. //
  30. // fn foo(bar: u16) f16 { return 13.5 * bar; } // ERROR!
  31. // var foo: f16 = 13.5 * @as(u8, 5); // ERROR!
  32. // var foo: f16 = 13.5 * 5; // This is a safe compile-time
  33. // // conversion, so no problem!
  34. // var foo: f16 = 13.5 * 5.0; // No problem, both are floats
  35. //
  36. // Please fix the two float problems with this program and
  37. // display the result as a whole number.
  38. const print = @import("std").debug.print;
  39. pub fn main() void {
  40. // The approximate weight of the Space Shuttle upon liftoff
  41. // (including boosters and fuel tank) was 2,200 tons.
  42. //
  43. // We'll convert this weight from tons to kilograms at a
  44. // conversion of 907.18kg to the ton.
  45. var shuttle_weight: f16 = 907.18 * 2200;
  46. // By default, float values are formatted in scientific
  47. // notation. Try experimenting with '{d}' and '{d:.3}' to see
  48. // how decimal formatting works.
  49. print("Shuttle liftoff weight: {d:.0}kg\n", .{shuttle_weight});
  50. }
  51. // Floating further:
  52. //
  53. // As an example, Zig's f16 is a IEEE 754 "half-precision" binary
  54. // floating-point format ("binary16"), which is stored in memory
  55. // like so:
  56. //
  57. // 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 0
  58. // | |-------| |-----------------|
  59. // | exponent significand
  60. // |
  61. // sign
  62. //
  63. // This example is the decimal number 3.140625, which happens to
  64. // be the closest representation of Pi we can make with an f16
  65. // due to the way IEEE-754 floating points store digits:
  66. //
  67. // * Sign bit 0 makes the number positive.
  68. // * Exponent bits 10000 are a scale of 16.
  69. // * Significand bits 1001001000 are the decimal value 584.
  70. //
  71. // IEEE-754 saves space by modifying these values: the value
  72. // 01111 is always subtracted from the exponent bits (in our
  73. // case, 10000 - 01111 = 1, so our exponent is 2^1) and our
  74. // significand digits become the decimal value _after_ an
  75. // implicit 1 (so 1.1001001000 or 1.5703125 in decimal)! This
  76. // gives us:
  77. //
  78. // 2^1 * 1.5703125 = 3.140625
  79. //
  80. // Feel free to forget these implementation details immediately.
  81. // The important thing to know is that floating point numbers are
  82. // great at storing big and small values (f64 lets you work with
  83. // numbers on the scale of the number of atoms in the universe),
  84. // but digits may be rounded, leading to results which are less
  85. // precise than integers.
  86. //
  87. // Fun fact: sometimes you'll see the significand labeled as a
  88. // "mantissa" but Donald E. Knuth says not to do that.
  89. //
  90. // C compatibility fact: There is also a Zig floating point type
  91. // specifically for working with C ABIs called c_longdouble.