Class: Bytepack::Decimal
Constant Summary
collapse
- DIRECTIVE =
'C16'
- NULL_INDICATOR =
NULL indicator for object type serializations
-170141183460469231731687303715884105728
- LENGTH =
16
- PRECISION =
38
- SCALE =
12
Class Method Summary
collapse
Methods inherited from Basic
bytesToInt, intToBytes, preprocess
Methods inherited from Struct
classifyDataType, config, packingDataType, single_type_array?, testpacking
Class Method Details
.deserialize(val, offset = 0) ⇒ Object
37
38
39
40
41
42
43
44
|
# File 'lib/bytepack/basic/fixed_size/decimal.rb', line 37
def deserialize(val, offset = 0)
unscaled = bytesToInt(self::LENGTH, val, offset)
if unscaled != self::NULL_INDICATOR
unscaled = unscaled.to_s
scaled = unscaled.insert(unscaled.size - self::SCALE, ".")
BigDecimal(scaled)
end
end
|
.pack(val) ⇒ Object
13
14
15
|
# File 'lib/bytepack/basic/fixed_size/decimal.rb', line 13
def pack(val)
(val == self::NULL_INDICATOR || val.nil?) ? intToBytes(self::LENGTH, self::NULL_INDICATOR) : serialize(val)
end
|
.serialize(val) ⇒ Object
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
# File 'lib/bytepack/basic/fixed_size/decimal.rb', line 21
def serialize(val)
num = case val
when BigDecimal then val
else val.to_d
end
sign, digits, base, exponent = *num.split
scale = digits.size - exponent
precision = digits.size
raise(::ArgumentError, "Scale of this decimal is #{scale} and the max is #{self::SCALE}") if scale > self::SCALE
rest = precision - scale
raise(::ArgumentError, "Precision to the left of the decimal point is #{rest} and the max is #{self::PRECISION-self::SCALE}") if rest > 26
scale_factor = self::SCALE - scale
unscaled_int = sign * digits.to_i * base ** scale_factor intToBytes(self::LENGTH, unscaled_int)
end
|
.unpack(bytes, offset = 0) ⇒ Object
17
18
19
|
# File 'lib/bytepack/basic/fixed_size/decimal.rb', line 17
def unpack(bytes, offset = 0)
[deserialize(bytes, offset), offset + self::LENGTH]
end
|