# Basic Types

Haxe provides several basic types:

• `Int` and `Float`, for numeric values.
• `Bool` for boolean/logical values, which may be either `true` or `false`.

# Numeric Types

Haxe provides two basic numeric types: `Int` for integer values and `Float` for floating-point values.

Arithmetic operations (`+`, `-`, `*`, and `/`) between these two numeric types are conservative (adding two `Int` together gives an `Int`), except for division which always returns a `Float`.

Bitwise operators (`<<`, >>`, `>>>`, `&`, `|`, `^`, `~`) may only be used on two `Int`s, and subsequently return an `Int''.

## Conversion

Every `Int` value can be used at the place a `Float` value is otherwise required.

On the other hand, in order to convert an `Float` to an `Int` you may use one of the following functions:

• `Std.int` will round towards zero, usually the fastest operation
• `Math.round` will round to the nearest integer
• `Math.ceil` will round towards positive infinity
• `Math.floor` will round towards negative infinity

## Overflows

For performance reasons, Haxe does not enforce any overflow behavior. It's up to the target platforms to worry about that.

Here's some notes about the way overflows are performed per-platform :

• C++, Java, C# and Neko use 32-bit integer values, with the usual overflow practices
• Flash AVM2 also uses 32-bit integers, but higher integers are memory-boxed so they may be slower
• PHP, Javascript, and Flash 8 do not have native Int values, so overflow will only occur if the value reach the float limit (`2^52` for double). In this case, however, all bitwise operations will result in a 32-bit overflow.

You can use the `haxe.Int32` and `haxe.Int64` classes to perform operations that correctly overflow on both 32 and 64 bits, regardless of the target platform.

# Nullability

To preserve the target's native behavior while maintaining performance, the default values of of certain types may vary from target to target. The reason is that Haxe want to get the best speed for each platform, and then needs to make a few compromises:

• Making all type nullable would slowdown static platforms a lot
• Making sure all `null` values are transformed into the corresponding default value would slowdown dynamic platforms a lot

So instead of enforcing a single behavior, we prefer to specify how Haxe will behave, so developers can plan or adapt their code accordingly. The compiler error messages will also greatly help in the transition between different types of platforms.

## Dynamically-Typed Platforms

On dynamically-typed platforms (Javascript, PHP, Neko, Flash 8) : every value can be `null`, and is `null` by default if not initialized. You can freely test for `null` equality without having to provide extra type information.

## Statically-Typed Platforms

On statically-typed platforms (Flash, C++, Java, C#), basic types have their own default values :

• every `Int` is by default initialized to 0
• every `Float` is by default initialized to `NaN` on Flash9+, and to 0.0 on CPP, Java and C#
• every `Bool` is by default initialized to `false`

It is not possible to store a `null` value into a basic type, unless you type it using `Null<T>` modifier :

```var a : Int = null; // error on static platforms
var b : Null<Int> = null; // allowed```

It is also not possible to compare a basic type value, unless you type it using `Null<T>` modifier :

```var a : Int = 0;
if( a == null ) { ... } // error on static platforms
var b : Null<Int> = 0;
if( b != null ) { .... } // allowed```

If you assign a `Null<T>` (or a `Dynamic`) value which contains `null` to the corresponding (unnullable) basic type, you will get the default value instead :

```var n : Null<Int> = null;
var a : Int = n;
trace(a); // 0 on static platforms```

## Optional Parameters and Nullability

Optional parameters have also a specific behavior with regards to nullability.

In particular, we have to be able to make the difference between native optional parameters which are not nullable and Haxe ones which might be nullable. This diffence is made by the usage of a question-mark optional parameter :

```// x is Int (not nullable)
function foo( x : Int = 0 ) {...}
// y is Null<Int> (nullable)
function bar( ?y : Int ) {...}
// z is also Null<Int>
function opt( ?z : Int = -1 ) {...}```

In the case the optional parameter is nullable, then we can pass it `null` and check for `null` in all cases. If we omit the parameter when calling the method, the default value will be use (if any exist) or `null` instead.

In the case the optional parameter is not nullable, then we cannot pass `null` or check for `null` on static platforms. If we omit the parameter when calling the method, the default value will be used anyway.

## Impact on Standard Library

The standard library correctly type the cases when a nullable value can be returned, for instance Hash.get will return `Null<T>` and you can safely check for `null` after reading from a hash table :

```var h : Map<String, Int> = new Map();
var x = h.get("hello");
trace(x); // null on all platforms```

However please note that `Hash.set` will only be able to set the exact type specified in the hash table :

```var h : Map<String, Int> = new Map();
h.set("hello",null); // error on static platforms
var h2 : Map<String, Null<Int>> = new Map();
h2.set("hello",null); // allowed```

Array is another case that you need to be careful with : every access outside its allocated range will return the default value for the basic type, unless of course the content of the `Array` is nullable :

```var a = new Array<Int>();
trace(a[5]); // 0 on static platforms
a.push(null); // not allowed on static platforms
var b = new Array<Null<Int>>();
trace(b[5]); // null
b.push(null); // allowed```

## Impact on cross-platformability

There are two cases to consider when porting some code here.

Porting some code from a dynamic platform to a static one (from JS to CPP for instance) is quite easy : every place you compare with a `null` you will get an error message and all you will have to do is to set the corresponding basic type to be `Null` :

```var x : Int = 0;
...
if( flag ) x = null; // error```

Can be changed to :

```var x : Null<Int> = 0;
...```

Porting some code from a static platform to a dynamic one require a bit more work : it will require you to ensure that all object member variables are correctly initialized to their default value in the class constructor :

```class Point {
var x : Int;
var y : Int;
public function new() {
// ensure correct initialization on dynamic platforms
x = y = 0;
}
}```

You will also have to make sure that you don't check for `== 0` when for instance reading outside of an `Array`. In that case you can either make the Array contain nullable value, or if you want to get best performances and can be sure that your code logic will not store any `0` value in the array use conditional compilation to perform the check depending on the platform :

```static inline var OUTSIDE : Int = #if js null #else 0 #end;

var a = new Array<Int>();
var out : Int = a[5];
if( out == OUTSIDE ) {
....
}```

## Impact on Speed

Please be aware than using `Null` modifier will make the manipulation of this value slower because it will usually require allocating some memory block to be able to differentiate between a null and an actual real value. However this will usually be more optimized than trying to emulate the same behavior by yourself.

version #19849, modified 2013-12-16 16:43:23 by seeker1983