Crystal 提供了多种不同的数字类型,各有各的用途。 例如,有些类型运算速度更快,但能表示的取值范围比其他的小;有些类型的取值范围更大,但速度更慢。
在 Crystal 中,整数类型既有有符号的,也有无符号的。 有符号整数可以表示正数,也可以表示负数。 无符号整数只能表示正数。
Crystal 中的有符号整数类型如下:
| Type | Size (bits) | Range |
|---|---|---|
Int8 |
8 | -128 至 127 |
Int16 |
16 | -32_768 至 32_767 |
Int32 |
32 | -2_147_483_648 至 2_147_483_647 |
Int64 |
64 | -9_223_372_036_854_775_808 至 9_223_372_036_854_775_807 |
Int128 |
128 | -170_141_183_460_469_231_731_687_303_715_884_105_728 至 170_141_183_460_469_231_731_687_303_715_884_105_727 |
较小的类型占用的内存更少,速度也更快,但能表示的取值范围更小。
如果你确定数值会落在某个范围内,最好使用尽可能小的类型,以节省内存并提升性能。
默认的整数类型是 Int32。
要声明一个指定类型的整数,可以把类型名作为后缀,写成 <number>_I <bit>。
1_i8.class
# => Int8
你可以用 to_i<bit> 方法在不同整数类型之间转换。
to_i 方法会转换成默认的整数类型 Int32。
1_i8.to_i16.class
# => Int16
2_i16.to_i.class
# => Int32
Crystal 中的无符号整数类型如下:
UInt8, UInt16, UInt32, UInt64, UInt128
有符号整数和无符号整数唯一的区别在于,无符号整数只能是正数。
要声明一个指定类型的无符号整数,可以把类型名作为后缀,写成 <number>_u<bit>。
你可以用 to_u<bit> 方法在不同无符号整数类型之间转换。
to_u 方法会转换成默认的无符号整数类型 UInt32。
1_u8.to_u16.class
# => UInt16
Crystal 中的浮点数类型如下:
| Type | Size (bits) | Range |
|---|---|---|
Float32 |
32 | 1.2E-38 to 3.4E+38 |
Float64 |
64 | 2.3E-308 to 1.7E+308 |
浮点数类型有两种,其中一种比另一种精度更高。
默认的浮点数类型是 Float64。
你可以用 to_f<bit> 方法在不同浮点数类型之间转换。
to_f 方法会转换成默认的浮点数类型 Float64。
ESA(Exercism Space Agency)正在全速规划一次前往火星卫星 Phobos 的新任务。这次任务的目标是让探测器降落在 Phobos 表面,并回传有关该表面的数据。ESA 请你帮忙为探测器构建导航计算机。导航计算机的内存有限,所以我们需要让内存占用尽可能低。因此,我们需要使用合适的数据类型。
导航计算机需要知道太空中某些物体之间的距离,才能进行正确的计算。距离以千米为单位。
定义以下常量:
NEPTUNE_DISTANCE的值为4_400_000_000,应存储为Int64
MARS_DISTANCE的值为227_940_000,应存储为Int32
ATMOSPHERE_DISTANCE的值为10_000,应存储为Int16
导航计算机需要知道太空中某些物体的面积,才能进行正确的计算。 面积不能为负数。 工程师原本计划让程序在面积为负数时产生溢出错误。 但是,工程师忘了把有符号整数改成无符号整数。
因此,工程师希望有一个能把有符号整数转换为无符号整数的程序。
实现Navigation#correct_area_analysis方法,它接受一个measurement作为实参,并返回 32 位无符号整数形式的面积。
给定的面积总能放进一个 32 位的无符号整数。
measurement = 52554
measurement.class
# => Int32
Navigation.new.correct_area_analysis(measurement)
# => 52554
Navigation.new.correct_area_analysis(measurement).class
# => UInt32
导航计算机需要知道探测器的速度。 速度以 m/s 为单位。
要计算速度,我们需要知道所走的距离,以及走完这段距离所用的时间。 然后用距离除以时间。
速度不必非常精确,而且永远不会是一个很大的数。
因此,我们可以使用Float32。
实现Navigation#calculate_velocity方法,它接受distance和time作为实参,并返回 32 位Float形式的速度。
distance = 52554
time = 2.5
Navigation.new.calculate_velocity(distance, time)
# => 21021.6
Navigation.new.calculate_velocity(distance, time).class
# => Float32