txt: ## numerics.md
  ## Chunk 1 of 2
  Numerics
  
  Numeric types available in Raku
  
  # [`Int`](/type/Int)[§](#Int "direct link")
  
  The [`Int`](/type/Int) type offers arbitrary-size integer numbers. They can get as big as your computer memory allows, although some implementations choose to throw a numeric overflow error when asked to produce integers of truly staggering size:
  
  ```raku
  say 10**600**600
  # OUTPUT: «Numeric overflow␤»
  
  ```
  
  Unlike some languages, division performed using [`/` operator](/routine/$SOLIDUS) when both operands are of [`Int`](/type/Int) type, would produce a fractional number, without any rounding performed.
  
  ```raku
  say 4/5; # OUTPUT: «0.8␤»
  
  ```
  
  The type produced by this division is either a [`Rat`](/type/Rat) or a [`Num`](/type/Num) type. The [`Rat`](/type/Rat) is produced if, after reduction, the fraction's denominator is smaller than 64 bits, otherwise a [`Num`](/type/Num) type is produced.
  
  The [div](/routine/div) and [narrow](/routine/narrow) routines can be helpful if you wish to end up with an [`Int`](/type/Int) result, whenever possible. The [div](/routine/div) operator performs integer division, discarding the remainder, while [narrow](/routine/narrow) fits the number into the narrowest type it'll fit:
  
  ```raku
  say 5 div 2; # OUTPUT: «2␤»
  
  # Result `2` is narrow enough to be an Int:
  say (4/2).narrow; # OUTPUT: «2␤»
  say (4/2).narrow.^name; # OUTPUT: «Int␤»
  
  # But 2.5 has fractional part, so it ends up being a Rat type:
  say (5/2).narrow.^name; # OUTPUT: «Rat␤»
  say (5/2).narrow;       # OUTPUT: «2.5␤»
  
  # Denominator is too big for a Rat, so a Num is produced:
  say 1 / 10⁹⁹; # OUTPUT: «1e-99␤»
  
  ```
  
  Raku has a [`FatRat`](/type/FatRat) type that offers arbitrary precision fractions. How come a limited-precision [`Num`](/type/Num) is produced instead of a [`FatRat`](/type/FatRat) type in the last example above? The reason is: performance. Most operations are fine with a little bit of precision lost and so do not require the use of a more expensive [`FatRat`](/type/FatRat) type. You'll need to instantiate one yourself if you wish to have the extra precision.
  
  # [`Num`](/type/Num)[§](#Num "direct link")
  
  The [`Num`](/type/Num) type offers [double-precision floating-point](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) decimal numbers, sometimes called "doubles" in other languages.
  
  A [`Num`](/type/Num) literal is written with the exponent separated using the letter `e`. Keep in mind that the letter `e` **is required** even if the exponent is zero, as otherwise you'll get a [`Rat`](/type/Rat) rational literal instead:
  
  ```raku
  say 42e0.^name; # OUTPUT: «Num␤»
  say 42.0.^name; # OUTPUT: «Rat␤»
  
  ```
  
  Case-sensitive words [Inf](/type/Num#Inf) and [NaN](/type/Num#NaN) represent the special values infinity and not-a-number respectively. The U+221E INFINITY (`∞`) character can be used instead of [Inf](/type/Num#Inf):
  
  Raku follows the [IEEE 754-2008 Standard for Floating-Point Arithmetic](https://en.wikipedia.org/wiki/IEEE_754) as much as possible, with more conformance planned to be implemented in later language versions. The language guarantees the closest representable number is chosen for any given [`Num`](/type/Num) literal and does offer support for negative zero and [denormals](https://en.wikipedia.org/wiki/Denormal_number) (also known as "subnormals").
  
  Keep in mind that output routines like [say](/routine/say) or [put](/routine/put) do not try very hard to distinguish between how [`Numeric`](/type/Numeric) types are output and may choose to display a [`Num`](/type/Num) as an [`Int`](/type/Int) or a [`Rat`](/type/Rat) number. For a more definitive string to output, use the [raku](/routine/raku) method:
  
  ```raku
  say  1e0;      # OUTPUT: «1␤»
  say .5e0;      # OUTPUT: «0.5␤»
  say  1e0.raku; # OUTPUT: «1e0␤»
  say .5e0.raku; # OUTPUT: «0.5e0␤»
  
  ```
  
  # [`Complex`](/type/Complex)[§](#Complex "direct link")
  
  The [`Complex`](/type/Complex) type numerics of the [complex plane](https://en.wikipedia.org/wiki/Complex_plane). The [`Complex`](/type/Complex) objects consist of two [`Num`](/type/Num) objects representing the [real](/routine/re) and [imaginary](/routine/im) portions of the complex number.
  
  To create a [`Complex`](/type/Complex), you can use the [postfix `i` operator](/routine/i) on any other non-complex number, optionally setting the real part with addition. To use the `i` operator on `NaN` or `Inf` literals, separate it from them with a backslash.
  
  ```raku
  say 42i;      # OUTPUT: «0+42i␤»
  say 73+42i;   # OUTPUT: «73+42i␤»
  say 73+Inf\i; # OUTPUT: «73+Inf\i␤»
  
  ```
  
  Keep in mind the above syntax is just an addition expression and precedence rules apply. It also cannot be used in places that forbid expressions, such as literals in routine parameters.
  
  ```raku
  # Precedence of `*` is higher than that of `+`
  say 2 * 73+10i; # OUTPUT: «146+10i␤»
  
  ```
  
  To avoid these issues, you can choose to use the [`Complex`](/type/Complex) literal syntax instead, which involves surrounding the real and imaginary parts with angle brackets, *without any spaces*:
  
  ```raku
  say 2 * <73+10i>; # OUTPUT: «146+20i␤»
  
  multi how-is-it (<2+4i>) { say "that's my favorite number!" }
  multi how-is-it (|)      { say "meh"                        }
  how-is-it 2+4i;  # OUTPUT: «that's my favorite number!␤»
  how-is-it 3+2i;  # OUTPUT: «meh␤»
  
  ```
  
  # [`Rational`](/type/Rational)[§](#Rational "direct link")
  
  The types that do the [`Rational`](/type/Rational) role offer high-precision and arbitrary-precision decimal numbers. Since the higher the precision the larger the performance penalty, the [`Rational`](/type/Rational) types come in two flavors: [`Rat`](/type/Rat) and [`FatRat`](/type/FatRat). The [`Rat`](/type/Rat) is the most often-used variant that degrades into a [`Num`](/type/Num) in most cases, when it can no longer hold all of the requested precision. The [`FatRat`](/type/FatRat) is the arbitrary-precision variant that keeps growing to provide all of the requested precision.
  
  ## [`Rat`](/type/Rat)[§](#Rat "direct link")
  
  The most common of [`Rational`](/type/Rational) types. It supports rationals with denominators as large as 64 bits (after reduction of the fraction to the lowest denominator). [`Rat`](/type/Rat) objects with larger denominators can be created directly, however, when [`Rat`](/type/Rat)s with such denominators are the result of mathematical operations, they degrade to a [`Num`](/type/Num) object.
  
  The [`Rat`](/type/Rat) literals use syntax similar to [`Num`](/type/Num) literals in many other languages, using the dot to indicate the number is a decimal:
  
  ```raku
  say .1 + .2 == .3; # OUTPUT: «True␤»
  
  ```
  
  If you try to execute a statement similar to the above in many common languages, you'll get `False` as the answer, due to imprecision of floating point math. To get the same result in Raku, you'd have to use [`Num`](/type/Num) literals instead:
  
  ```raku
  say .1e0 + .2e0 == .3e0; # OUTPUT: «False␤»
  
  ```
  
  You can also use [`/` division operator](/routine/$SOLIDUS) with [`Int`](/type/Int) or [`Rat`](/type/Rat) objects to produce a [`Rat`](/type/Rat):
  
  ```raku
  say 3/4;     # OUTPUT: «0.75␤»
  say 3/4.2;   # OUTPUT: «0.714286␤»
  say 1.1/4.2; # OUTPUT: «0.261905␤»
  
  ```
  
  Keep in mind the above syntax is just a division expression and precedence rules apply. It also cannot be used in places that forbid expressions, such as literals in routine parameters.
  
  ```raku
  # Precedence of power operators is higher than division
  say 3/2²; # OUTPUT: «0.75␤»
  
  ```
  
  To avoid these issues, you can choose to use the [`Rational`](/type/Rational) literal syntax instead, which involves surrounding the numerator and denominator with angle brackets, *without any spaces*:
  
  ```raku
  say <3/2>²; # OUTPUT: «2.25␤»
  
  multi how-is-it (<3/2>) { say "that's my favorite number!" }
  multi how-is-it (|)     { say "meh"                        }
  how-is-it 3/2;  # OUTPUT: «that's my favorite number!␤»
  how-is-it 1/3;  # OUTPUT: «meh␤»
  
  ```
  
  Lastly, any Unicode character with property `No` that represents a fractional number can be used as a [`Rat`](/type/Rat) literal:
  
  ```raku
  say ½ + ⅓ + ⅝ + ⅙; # OUTPUT: «1.625␤»
  
  ```
  
  ### [Degradation to](#Numerics "go to top of document") [`Num`](/type/Num)[§](#Degradation_to_Num "direct link")
  
  If a *mathematical operation* that produces a [`Rat`](/type/Rat) answer would produce a [`Rat`](/type/Rat) with denominator larger than 64 bits, that operation would instead return a [`Num`](/type/Num) object. When *constructing* a [`Rat`](/type/Rat) (i.e. when it is not a result of some mathematical expression), however, a larger denominator can be used:
  
  ```raku
  my $a = 1 / (2⁶⁴ - 1);
  say $a;                   # OUTPUT: «0.000000000000000000054␤»
  say $a.^name;             # OUTPUT: «Rat␤»
  say $a.nude;              # OUTPUT: «(1 18446744073709551615)␤»
  
  my $b = 1 / 2⁶⁴;
  say $b;                   # OUTPUT: «5.421010862427522e-20␤»
  say $b.^name;             # OUTPUT: «Num␤»
  
  my $c = Rat.new(1, 2⁶⁴);
  say $c;                   # OUTPUT: «0.000000000000000000054␤»
  say $c.^name;             # OUTPUT: «Rat␤»
  say $c.nude;              # OUTPUT: «(1 18446744073709551616)␤»
  say $c.Num;               # OUTPUT: «5.421010862427522e-20␤»
  ```
  
  ## [`FatRat`](/type/FatRat)[§](#FatRat "direct link")
  
  The last [`Rational`](/type/Rational) type—[`FatRat`](/type/FatRat)—keeps all of the precision you ask of it, storing the numerator and denominator as two [`Int`](/type/Int) objects. A [`FatRat`](/type/FatRat) is more infectious than a [`Rat`](/type/Rat), so many math operations with a [`FatRat`](/type/FatRat) will produce another [`FatRat`](/type/FatRat), preserving all of the available precision. Where a [`Rat`](/type/Rat) degrades to a [`Num`](/type/Num), math with a [`FatRat`](/type/FatRat) keeps chugging along:
  
  ```raku
  say ((42 + Rat.new(1,2))/999999999999999999).^name;         # OUTPUT: «Rat␤»
  say ((42 + Rat.new(1,2))/9999999999999999999).^name;        # OUTPUT: «Num␤»
  say ((42 + FatRat.new(1,2))/999999999999999999).^name;      # OUTPUT: «FatRat␤»
  say ((42 + FatRat.new(1,2))/99999999999999999999999).^name; # OUTPUT: «FatRat␤»
  
  ```
  
  There's no special operator or syntax available for construction of [`FatRat`](/type/FatRat) objects. Simply use the `FatRat.new` method, giving numerator as first positional argument and denominator as the second.
  
  If your program requires a significant amount of [`FatRat`](/type/FatRat) creation, you could create your own custom operator:
  
  ```raku
  sub infix:<🙼> { FatRat.new: $^a, $^b }
  say (1🙼3).raku; # OUTPUT: «FatRat.new(1, 3)␤»
  
  ```
  
  ## [Printing rationals](#Numerics "go to top of document")[§](#Printing_rationals "direct link")
  
  Keep in mind that output routines like [say](/routine/say) or [put](/routine/put) do not try very hard to distinguish between how [`Numeric`](/type/Numeric) types are output and may choose to display a [`Num`](/type/Num) as an [`Int`](/type/Int) or a [`Rat`](/type/Rat) number. For a more definitive string to output, use the [raku](/routine/raku) method:
  
  ```raku
  say 1.0;        # OUTPUT: «1␤»
  say ⅓;          # OUTPUT: «0.333333␤»
  say 1.0.raku;   # OUTPUT: «1.0␤»
  say ⅓.raku;     # OUTPUT: «<1/3>␤»
  
  ```
  
  For even more information, you may choose to see the [`Rational`](/type/Rational) object in the [nude](/routine/nude), displaying its **nu**merator and **de**nominator:
  
  ```raku
  say ⅓;          # OUTPUT: «0.333333␤»
  say 4/2;        # OUTPUT: «2␤»
  say ⅓.raku;     # OUTPUT: «<1/3>␤»
  say <4/2>.nude; # OUTPUT: «(2 1)␤»
  
  ```
  
  # [Division by zero](#Numerics "go to top of document")[§](#Division_by_zero "direct link")
  
  In many languages division by zero is an immediate exception. In Raku, what happens depends on what you're dividing and how you use the result.
  
  Raku follows [IEEE 754-2008 Standard for Floating-Point Arithmetic](https://en.wikipedia.org/wiki/IEEE_754), but for historical reasons 6.c and 6.d language versions do not comply fully. [`Num`](/type/Num) division by zero produces a [`Failure`](/type/Failure), while [`Complex`](/type/Complex) division by zero produces `NaN` components, regardless of what the numerator is.
  
  As of 6.e language, both [`Num`](/type/Num) and [`Complex`](/type/Complex) division by zero will produce an [`-Inf`](/type/Num#Inf), `+Inf`, or [NaN](/type/Num#NaN) depending on whether the numerator was negative, positive, or zero, respectively (for [`Complex`](/type/Complex) the real and imaginary components are [`Num`](/type/Num) and are considered separately).
  
  Division of [`Int`](/type/Int) numerics produces a [`Rat`](/type/Rat) object (or a [`Num`](/type/Num), if after reduction the denominator is larger than 64-bits, which isn't the case when you're dividing by zero). This means such division never produces an [`Exception`](/type/Exception) or a [`Failure`](/type/Failure). The result is a Zero-Denominator Rational, which can be explosive.
  
  ## [Zero-denominator rationals](#Numerics "go to top of document")[§](#Zero-denominator_rationals "direct link")
  
  A Zero-Denominator Rational is a numeric that does role [`Rational`](/type/Rational), which among core numerics would be [`Rat`](/type/Rat) and [`FatRat`](/type/FatRat) objects, which has denominator of zero. The numerator of such Rationals is normalized to `-1`, `0`, or `1` depending on whether the original numerator is negative, zero or positive, respectively.
  
  Operations that can be performed without requiring actual division to occur are non-explosive. For example, you can separately examine [numerator](/routine/numerator) and [denominator](/routine/denominator) in the [nude](/routine/nude) or perform mathematical operations without any exceptions or failures popping up.
  
  Converting zero-denominator rationals to [`Num`](/type/Num) follows the [IEEE](https://en.wikipedia.org/wiki/IEEE_754) conventions, and the result is an `-Inf`, `Inf`, or `NaN`, depending on whether the numerator is negative, positive, or zero, respectively. The same is true going the other way: converting `±Inf`/`NaN` to one of the [`Rational`](/type/Rational) types will produce a zero-denominator rational with an appropriate numerator:
  
  ```raku
  say  <1/0>.Num;   # OUTPUT: «Inf␤»
  say <-1/0>.Num;   # OUTPUT: «-Inf␤»
  say  <0/0>.Num;   # OUTPUT: «NaN␤»
  say Inf.Rat.nude; # OUTPUT: «(1 0)␤»
  
  ```
  
  All other operations that require non-[IEEE](https://en.wikipedia.org/wiki/IEEE_754) division of the numerator and denominator to occur will result in [`X::Numeric::DivideByZero`](/type/X/Numeric/DivideByZero) exception to be thrown. The most common of such operations would likely be trying to print or stringify a zero-denominator rational:
  
  ```raku
  say 0/0;
  # OUTPUT:
  # Attempt to divide by zero using div
  #  in block <unit> at -e line 1
  
  ```
  
  # [Allomorphs](#Numerics "go to top of document")[§](#Allomorphs "direct link")
  
  [Allomorphs](/language/glossary#Allomorph) are subclasses of two types that can behave as either of them. For example, the allomorph [`IntStr`](/type/IntStr) is the subclass of [`Int`](/type/Int) and [`Str`](/type/Str) types and will be accepted by any type constraint that requires an [`Int`](/type/Int) or [`Str`](/type/Str) object.
  
  Allomorphs can be created using [angle brackets](/language/quoting#Word_quoting:_<_>), either used standalone or as part of a hash key lookup; directly using method `.new` and are also provided by some constructs such as parameters of [`sub MAIN`](/language/functions#sub_MAIN).
  
  ```raku
  say <42>.^name;                 # OUTPUT: «IntStr␤»
  say <42e0>.^name;               # OUTPUT: «NumStr␤»
  say < 42+42i>.^name;            # OUTPUT: «ComplexStr␤»
  say < 1/2>.^name;               # OUTPUT: «RatStr␤»
  say <0.5>.^name;                # OUTPUT: «RatStr␤»
  
  @*ARGS = "42";
  sub MAIN($x) { say $x.^name }   # OUTPUT: «IntStr␤»
  
  say IntStr.new(42, "42").^name; # OUTPUT: «IntStr␤»
  
  ```
  
  A couple of constructs above have a space after the opening angle bracket. That space isn't accidental. Numerics that are often written using an operator, such as `1/2` ([`Rat`](/type/Rat), division operator) and `1+2i` ([`Complex`](/type/Complex), addition) can be written as a literal that doesn't involve the use of an operator: angle brackets *without* any spaces between the angle brackets and the characters inside. By adding spaces within the angle brackets, we tell the compiler that not only we want a [`Rat`](/type/Rat) or [`Complex`](/type/Complex) literal, but we also want it to be an allomorph: the [`RatStr`](/type/RatStr) or [`ComplexStr`](/type/ComplexStr), in this case.
  
  If the numeric literal doesn't use any operators, then writing it inside the angle brackets, even without including any spaces within, would produce the allomorph. (Logic: if you didn't want the allomorph, you wouldn't use the angle brackets. The same isn't true for operator-using numbers as some constructs, such as signature literals, do not let you use operators, so you can't just omit angle brackets for such numeric literals).
  
  ## [Available allomorphs](#Numerics "go to top of document")[§](#Available_allomorphs "direct link")
  
  The core language offers the following allomorphs:
  
  | Type | Allomorph of | Example |
  | --- | --- | --- |
  | IntStr | Int and Str | <42> |
  | NumStr | Num and Str | <42e0> |
  | ComplexStr | Complex and Str | < 1+2i> |
  | RatStr | Rat and Str | <1.5> |
  
  Note: there is no `FatRatStr` type.
  
  ## [Coercion of allomorphs](#Numerics "go to top of document")[§](#Coercion_of_allomorphs "direct link")
  
  Keep in mind that allomorphs are simply subclasses of the types they represent. Just as a variable or parameter type-constrained to `Foo` can accept any subclass of `Foo`, so will a variable or parameter type-constrained to [`Int`](/type/Int) will accept an [`IntStr`](/type/IntStr) allomorph:
  
  ```raku
  sub foo(Int $x) { say $x.^name }
  foo <42>;                          # OUTPUT: «IntStr␤»
  my Num $y = <42e0>;
  say $y.^name;                      # OUTPUT: «NumStr␤»
  
  ```
  
  This also applies to parameter [coercers](/language/signatures#Coercion_type):
  
  ```raku
  sub foo(Int(Cool) $x) { say $x.^name }
  foo <42>;  # OUTPUT: «IntStr␤»
  
  ```
  
  The given allomorph is *already* an object of type [`Int`](/type/Int), so it does not get converted to a "plain" [`Int`](/type/Int) in this case.
  
  The power of allomorphs would be severely diminished if there were no way to "collapse" them to one of their components. Thus, if you explicitly call a method with the name of the type to coerce to, you'll get just that component. The same applies to any proxy methods, such as calling method [`.Numeric`](/routine/Numeric) instead of [`.Int`](/routine/Int) or using the [`prefix:<~>` operator](/routine/~) instead of [`.Str`](/routine/Str) method call.
  
  ```raku
  my $al := IntStr.new: 42, "forty two";
  say $al.Str;  # OUTPUT: «forty two␤»
  say +$al;     # OUTPUT: «42␤»
  
  say <1/99999999999999999999>.Rat.^name;    # OUTPUT: «Rat␤»
  say <1/99999999999999999999>.FatRat.^name; # OUTPUT: «FatRat␤»
  
  ```
  
  A handy way to coerce a whole list of allomorphs is by applying the [hyper operator](/language/operators#Hyper_operators) to the appropriate prefix:
  
  ```raku
  say map *.^name,   <42 50e0 100>;  # OUTPUT: «(IntStr NumStr IntStr)␤»
  say map *.^name, +«<42 50e0 100>;  # OUTPUT: «(Int Num Int)␤»
  say map *.^name, ~«<42 50e0 100>;  # OUTPUT: «(Str Str Str)␤»
  
  ```
  
  ## [Object identity](#Numerics "go to top of document")[§](#Object_identity "direct link")
  
  The above discussion on coercing allomorphs becomes more important when we consider object identity. Some constructs utilize it to ascertain whether two objects are "the same". And while to humans an allomorphic `42` and regular `42` might appear "the same", to those constructs, they're entirely different objects:
  
  ```raku
  # "42" shows up twice in the result: 42 and <42> are different objects:
  say unique 1, 1, 1, 42, <42>; # OUTPUT: «(1 42 42)␤»
  # Use a different operator to `unique` with:
  say unique :with(&[==]), 1, 1, 1, 42, <42>; # OUTPUT: «(1 42)␤»
  # Or coerce the input instead (faster than using a different `unique` operator):
  say unique :as(*.Int), 1, 1, 1, 42, <42>; # OUTPUT: «(1 42)␤»
  say unique +«(1, 1, 1, 42, <42>);         # OUTPUT: «(1 42)␤»
  
  # Parameterized Hash with `Any` keys does not stringify them; our key is of type `Int`:
  my %h{Any} = 42 => "foo";
  # But we use the allomorphic key of type `IntStr`, which is not in the Hash:
  say %h<42>:exists;           # OUTPUT: «False␤»
  # Must use curly braces to avoid the allomorph:
  say %h{42}:exists;           # OUTPUT: «True␤»
  
  # We are using a set operator to look up an `Int` object in a list of `IntStr` objects:
  say 42 ∈ <42 100 200>; # OUTPUT: «False␤»
  # Convert it to an allomorph:
  say <42> ∈ <42 100 200>; # OUTPUT: «True␤»
  # Or convert the items in the list to plain `Int` objects:
  say 42 ∈ +«<42 100 200>; # OUTPUT: «True␤»
  
  ```
  
  Be mindful of these object identity differences and coerce your allomorphs as needed.
  
  ## [Transforming non-Allomorphs](#Numerics "go to top of document")[§](#Transforming_non-Allomorphs "direct link")
  
  When we create variables explicitly as [`Str`](/type/Str) or [`Numeric`](/type/Numeric) types, they are not [`Allomorph`](/type/Allomorph)s:
  
  ```raku
  my $a = "010"; say $a.^name; # OUTPUT: «Str␤»
  my $b = 42;    say $b.^name; # OUTPUT: «Int␤»
  
  ```
  
  We can then explicitly transform them to their [`Allomorph`](/type/Allomorph) counterparts:
  
  ```raku
  $a .= Numeric; # OUTPUT: «10␤»
  say $a.^name;  # OUTPUT: «Int␤»
  $b .= Str;   ; # OUTPUT: «42␤»
  say $b.^name;  # OUTPUT: «Str␤»
  
  ```
  
  Or we can coerce them into their other forms naturally:
  
  ```raku
  my $a = "010"; say $a.^name; # OUTPUT: «Str␤»
  my $b = $a + 1;              # OUTPUT: «11␤»
  say $b.^name;                # OUTPUT: «Int␤»
  
  ```
  
  # [Native numerics](#Numerics "go to top of document")[§](#Native_numerics "direct link")
  
  As the name suggests, native numerics offer access to native numerics—i.e. those offered directly by your hardware. This in turn offers two features: overflow/underflow and better performance.
  
  **NOTE:** at the time of this writing (2018.05), certain implementations (such as Rakudo) offer somewhat spotty details on native types, such as whether `int64` is available and is of 64-bit size on 32-bit machines, and how to detect when your program is running on such hardware.
  
  ## [Available native numerics](#Numerics "go to top of document")[§](#Available_native_numerics "direct link")
  
  | Native type | Base numeric | Size |
  | --- | --- | --- |
  | int | integer | 64-bits |
  | int8 | integer | 8-bits |
  | int16 | integer | 16-bits |
  | int32 | integer | 32-bits |
  | int64 | integer | 64-bits |
  | uint | unsigned integer | 64-bits |
  | uint8 | unsigned integer | 8-bits |
  | uint16 | unsigned integer | 16-bits |
  | uint32 | unsigned integer | 32-bits |
  | uint64 | unsigned integer | 64-bits |
  | num | floating point | 64-bits |
  | num32 | floating point | 32-bits |
  | num64 | floating point | 64-bits |
  | atomicint | integer | sized to offer CPU-provided atomic operations. (typically 64 bits on 64-bit platforms and 32 bits on 32-bit ones) |
  
  ## [Creating native numerics](#Numerics "go to top of document")[§](#Creating_native_numerics "direct link")
  
  To create a natively-typed variable or parameter, simply use the name of one of the available numerics as the type constraint:
  
  ```raku
  my int32 $x = 42;
  sub foo(num $y) {}
  class { has int8 $.z }
  
  ```
  
  At times, you may wish to coerce some value to a native type without creating any usable variables. There are no `.int` or similar coercion methods (method calls are latebound, so they're not well-suited for this purpose). Instead, simply use an anonymous variable:
  
  ```raku
  some-native-taking-sub( (my int $ = $y), (my int32 $ = $z) )
  
  ```
  
  ## [Overflow/Underflow](#Numerics "go to top of document")[§](#Overflow/Underflow "direct link")
  
  Trying to **assign** a value that does not fit into a particular native type, produces an exception. This includes attempting to give too large an argument to a native parameter:
  
  ```raku
  my int $x = 2¹⁰⁰;
  # OUTPUT:
  # Cannot unbox 101 bit wide bigint into native integer
  #  in block <unit> at -e line 1
  
  sub f(int $x) { $x }; say f 2⁶⁴
  # OUTPUT:
  # Cannot unbox 65 bit wide bigint into native integer
  #   in sub f at -e line 1
  #   in block <unit> at -e line 1
  
  ```
  
  However, modifying an already-existing value in such a way that it becomes too big/small, produces overflow/underflow behavior:
  
  ```raku
  my int $x = 2⁶³-1;
  say $x;             # OUTPUT: «9223372036854775807␤»
  say ++$x;           # OUTPUT: «-9223372036854775808␤»
  
  my uint8 $x;
  say $x;             # OUTPUT: «0␤»
  say $x -= 100;      # OUTPUT: «156␤»
  
  ```
  
  Creating objects that utilize native types does not involve direct assignment by the programmer; that is why these constructs offer overflow/underflow behavior instead of throwing exceptions.
  
  ```raku
  say Buf.new(1000, 2000, 3000).List; # OUTPUT: «(232 208 184)␤»
  say my uint8 @a = 1000, 2000, 3000; # OUTPUT: «232 208 184␤»
  
  ```
  
  ## [Auto-boxing](#Numerics "go to top of document")[§](#Auto-boxing "direct link")
  
  While they can be referred to as "native *types*", native numerics are not actually classes that have any sort of methods available. However, you *can* call any of the methods available on non-native versions of these numerics. What's going on?
  
  ```raku
  my int8 $x = -42;
  say $x.abs; # OUTPUT: «42␤»
  
  ```
  
  This behavior is known as "auto-boxing". The compiler automatically "boxes" the native type into a full-featured higher-level type with all the methods. In other words, the `int8` above was automatically converted to an [`Int`](/type/Int) and it's the [`Int`](/type/Int) class that then provided the [abs](/routine/abs) method that was called.
  
  This detail is significant when you're using native types for performance gains. If the code you're using results in a lot of auto-boxing being performed you might get *worse* performance with native types than you would with non-natives:
  
  ```raku
  my $a = -42;
  my int $a-native = -42;
  { for ^1000_000 { $a.abs        }; say now - ENTER now } # OUTPUT: «0.381