txt: ## numerics.md
  ## Chunk 2 of 2
  80862␤»
  { for ^1000_000 { $a-native.abs }; say now - ENTER now } # OUTPUT: «0.938720␤»
  
  ```
  
  As you can see above, the native variant is more than twice slower. The reason is the method call requires the native type to be boxed, while no such thing is needed in the non-native variant, hence the performance loss.
  
  In this particular case, we can simply switch to a subroutine form of [abs](/routine/abs), which can work with native types without boxing them. In other cases, you may need to seek out other solutions to avoid excessive autoboxing, including switching to non-native types for a portion of the code.
  
  ```raku
  my $a = -42;
  my int $a-native = -42;
  { for ^1000_000 { abs $a        }; say now - ENTER now } # OUTPUT: «0.38229177␤»
  { for ^1000_000 { abs $a-native }; say now - ENTER now } # OUTPUT: «0.3088305␤»
  
  ```
  
  ## [Default values](#Numerics "go to top of document")[§](#Default_values "direct link")
  
  Since there are no classes behind native types, there are no type objects you'd normally get with variables that haven't been initialized. Thus, native types are automatically initialized to zero. In 6.c language, native floating point types (`num`, `num32`, and `num64`) were initialized to value `NaN`; in 6.d language the default is `0e0`.
  
  ## [Native dispatch](#Numerics "go to top of document")[§](#Native_dispatch "direct link")
  
  It is possible to have native candidates alongside non-native candidates to, for example, offer faster algorithms with native candidates when sizes are predictable, but to fallback to slower non-native alternatives otherwise. The following are the rules concerning multi-dispatch involving native candidates.
  
  First, the size of the native type does not play a role in dispatch and an `int8` is considered to be the same as `int16` or `int`:
  
  ```raku
  multi foo(int   $x) { say "int" }
  multi foo(int32 $x) { say "int32" }
  foo my int $x = 42;
  # OUTPUT:
  # Ambiguous call to 'foo(Int)'; these signatures all match:
  # :(int $x)
  # :(int32 $x)
  
  ```
  
  Second, if a routine is an `only`—i.e. it is not a [`multi`](/language/functions#Multi-dispatch)—that takes a non-native type but a native one was given during the call, or vice-versa, then the argument will be auto-boxed or auto-unboxed to make the call possible. If the given argument is too large to fit into the native parameter, an exception will be thrown:
  
  ```raku
  -> int {}( 42 );            # OK; auto-unboxing
  -> int {}( 2¹⁰⁰ );          # Too large; exception
  -> Int {}( 2¹⁰⁰ );          # OK; non-native parameter
  -> Int {}( my int $ = 42 ); # OK; auto-boxing
  
  ```
  
  When it comes to [`multi`](/language/functions#Multi-dispatch) routines, native arguments will always be auto-boxed if no native candidates are available to take them:
  
  ```raku
  multi foo (Int $x) { $x }
  say foo my int $ = 42; # OUTPUT: «42␤»
  
  ```
  
  The same luxury is not afforded when going the other way. If only a native candidate is available, a non-native argument will *not* be auto-unboxed and instead an exception indicating no candidates matched will be thrown (the reason for this asymmetry is a native type can always be boxed, but a non-native may be too large to fit into a native):
  
  ```raku
  multi f(int $x) { $x }
  my $x = 2;
  say f $x;
  # OUTPUT:
  # Cannot resolve caller f(Int); none of these signatures match:
  #     (int $x)
  #   in block <unit> at -e line 1
  
  ```
  
  However, this rule is waived if a call is being made where one of the arguments is a native type and another one is a [numeric literal](/language/syntax#Number_literals):
  
  ```raku
  multi f(int, int) {}
  f 42, my int $x; # Successful call
  
  ```
  
  This way you do not have to constantly write, for example, `$n +> 2` as `$n +> (my int $ = 2)`. The compiler knows the literal is small enough to fit to a native type and converts it to a native.
  
  ## [Atomic operations](#Numerics "go to top of document")[§](#Atomic_operations "direct link")
  
  The language offers [some operations](/type/atomicint) that are guaranteed to be performed atomically, i.e. safe to be executed by multiple threads without the need for locking with no risk of data races.
  
  For such operations, the [`atomicint`](/type/atomicint) native type is required. This type is similar to a plain native [`int`](/native/int), except it is sized such that CPU-provided atomic operations can be performed upon it. On a 32-bit CPU it will typically be 32 bits in size, and on an a 64-bit CPU it will typically be 64 bits in size.
  
  ```raku
  # !!WRONG!! Might be non-atomic on some systems
  my int $x;
  await ^100 .map: { start $x⚛++ };
  say $x; # OUTPUT: «98␤»
  
  # RIGHT! The use of `atomicint` type guarantees operation is atomic
  my atomicint $x;
  await ^100 .map: { start $x⚛++ };
  say $x; # OUTPUT: «100␤»
  
  ```
  
  The similarity to `int` is present in multi dispatch as well: an [`atomicint`](/type/atomicint), plain `int`, and the sized `int` variants are all considered to be the same by the dispatcher and cannot be differentiated through multi-dispatch.
  
  # [Numeric infectiousness](#Numerics "go to top of document")[§](#Numeric_infectiousness "direct link")
  
  Numeric "infectiousness" dictates the resultant type when two numerics of different types are involved in some mathematical operations. A type is said to be more infectious than the other type if the result is of that type rather than the type of the other operand. For example, [`Num`](/type/Num) type is more infectious than an [`Int`](/type/Int), thus we can expect `42e0 + 42` to produce a [`Num`](/type/Num) as the result.
  
  The infectiousness is as follows, with the most infectious type listed first:
  
  * Complex
  * Num
  * FatRat
  * Rat
  * Int
  
  ```raku
  say (2 + 2e0).^name; # Int + Num => OUTPUT: «Num␤»
  say (½ + ½).^name; # Rat + Rat => OUTPUT: «Rat␤»
  say (FatRat.new(1,2) + ½).^name; # FatRat + Rat => OUTPUT: «FatRat␤»
  
  ```
  
  The allomorphs have the same infectiousness as their numeric component. Native types get autoboxed and have the same infectiousness as their boxed variant.
  