xtquant.xtbson.bson36.decimal128
Tools for working with the BSON decimal128 type.
New in version 3.4.
The Decimal128 BSON type requires MongoDB 3.4+.
1# Copyright 2016-present MongoDB, Inc. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Tools for working with the BSON decimal128 type. 16 17.. versionadded:: 3.4 18 19.. note:: The Decimal128 BSON type requires MongoDB 3.4+. 20""" 21 22import decimal 23import struct 24import sys 25 26_PACK_64 = struct.Struct("<Q").pack 27_UNPACK_64 = struct.Struct("<Q").unpack 28 29_EXPONENT_MASK = 3 << 61 30_EXPONENT_BIAS = 6176 31_EXPONENT_MAX = 6144 32_EXPONENT_MIN = -6143 33_MAX_DIGITS = 34 34 35_INF = 0x7800000000000000 36_NAN = 0x7C00000000000000 37_SNAN = 0x7E00000000000000 38_SIGN = 0x8000000000000000 39 40_NINF = (_INF + _SIGN, 0) 41_PINF = (_INF, 0) 42_NNAN = (_NAN + _SIGN, 0) 43_PNAN = (_NAN, 0) 44_NSNAN = (_SNAN + _SIGN, 0) 45_PSNAN = (_SNAN, 0) 46 47_CTX_OPTIONS = { 48 "prec": _MAX_DIGITS, 49 "rounding": decimal.ROUND_HALF_EVEN, 50 "Emin": _EXPONENT_MIN, 51 "Emax": _EXPONENT_MAX, 52 "capitals": 1, 53 "flags": [], 54 "traps": [decimal.InvalidOperation, decimal.Overflow, decimal.Inexact], 55 "clamp": 1, 56} 57 58_DEC128_CTX = decimal.Context(**_CTX_OPTIONS.copy()) 59 60 61def create_decimal128_context(): 62 """Returns an instance of :class:`decimal.Context` appropriate 63 for working with IEEE-754 128-bit decimal floating point values. 64 """ 65 opts = _CTX_OPTIONS.copy() 66 opts["traps"] = [] 67 return decimal.Context(**opts) 68 69 70def _decimal_to_128(value): 71 """Converts a decimal.Decimal to BID (high bits, low bits). 72 73 :Parameters: 74 - `value`: An instance of decimal.Decimal 75 """ 76 with decimal.localcontext(_DEC128_CTX) as ctx: 77 value = ctx.create_decimal(value) 78 79 if value.is_infinite(): 80 return _NINF if value.is_signed() else _PINF 81 82 sign, digits, exponent = value.as_tuple() 83 84 if value.is_nan(): 85 if digits: 86 raise ValueError("NaN with debug payload is not supported") 87 if value.is_snan(): 88 return _NSNAN if value.is_signed() else _PSNAN 89 return _NNAN if value.is_signed() else _PNAN 90 91 significand = int("".join([str(digit) for digit in digits])) 92 bit_length = significand.bit_length() 93 94 high = 0 95 low = 0 96 for i in range(min(64, bit_length)): 97 if significand & (1 << i): 98 low |= 1 << i 99 100 for i in range(64, bit_length): 101 if significand & (1 << i): 102 high |= 1 << (i - 64) 103 104 biased_exponent = exponent + _EXPONENT_BIAS 105 106 if high >> 49 == 1: 107 high = high & 0x7FFFFFFFFFFF 108 high |= _EXPONENT_MASK 109 high |= (biased_exponent & 0x3FFF) << 47 110 else: 111 high |= biased_exponent << 49 112 113 if sign: 114 high |= _SIGN 115 116 return high, low 117 118 119class Decimal128(object): 120 """BSON Decimal128 type:: 121 122 >>> Decimal128(Decimal("0.0005")) 123 Decimal128('0.0005') 124 >>> Decimal128("0.0005") 125 Decimal128('0.0005') 126 >>> Decimal128((3474527112516337664, 5)) 127 Decimal128('0.0005') 128 129 :Parameters: 130 - `value`: An instance of :class:`decimal.Decimal`, string, or tuple of 131 (high bits, low bits) from Binary Integer Decimal (BID) format. 132 133 .. note:: :class:`~Decimal128` uses an instance of :class:`decimal.Context` 134 configured for IEEE-754 Decimal128 when validating parameters. 135 Signals like :class:`decimal.InvalidOperation`, :class:`decimal.Inexact`, 136 and :class:`decimal.Overflow` are trapped and raised as exceptions:: 137 138 >>> Decimal128(".13.1") 139 Traceback (most recent call last): 140 File "<stdin>", line 1, in <module> 141 ... 142 decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>] 143 >>> 144 >>> Decimal128("1E-6177") 145 Traceback (most recent call last): 146 File "<stdin>", line 1, in <module> 147 ... 148 decimal.Inexact: [<class 'decimal.Inexact'>] 149 >>> 150 >>> Decimal128("1E6145") 151 Traceback (most recent call last): 152 File "<stdin>", line 1, in <module> 153 ... 154 decimal.Overflow: [<class 'decimal.Overflow'>, <class 'decimal.Rounded'>] 155 156 To ensure the result of a calculation can always be stored as BSON 157 Decimal128 use the context returned by 158 :func:`create_decimal128_context`:: 159 160 >>> import decimal 161 >>> decimal128_ctx = create_decimal128_context() 162 >>> with decimal.localcontext(decimal128_ctx) as ctx: 163 ... Decimal128(ctx.create_decimal(".13.3")) 164 ... 165 Decimal128('NaN') 166 >>> 167 >>> with decimal.localcontext(decimal128_ctx) as ctx: 168 ... Decimal128(ctx.create_decimal("1E-6177")) 169 ... 170 Decimal128('0E-6176') 171 >>> 172 >>> with decimal.localcontext(DECIMAL128_CTX) as ctx: 173 ... Decimal128(ctx.create_decimal("1E6145")) 174 ... 175 Decimal128('Infinity') 176 177 To match the behavior of MongoDB's Decimal128 implementation 178 str(Decimal(value)) may not match str(Decimal128(value)) for NaN values:: 179 180 >>> Decimal128(Decimal('NaN')) 181 Decimal128('NaN') 182 >>> Decimal128(Decimal('-NaN')) 183 Decimal128('NaN') 184 >>> Decimal128(Decimal('sNaN')) 185 Decimal128('NaN') 186 >>> Decimal128(Decimal('-sNaN')) 187 Decimal128('NaN') 188 189 However, :meth:`~Decimal128.to_decimal` will return the exact value:: 190 191 >>> Decimal128(Decimal('NaN')).to_decimal() 192 Decimal('NaN') 193 >>> Decimal128(Decimal('-NaN')).to_decimal() 194 Decimal('-NaN') 195 >>> Decimal128(Decimal('sNaN')).to_decimal() 196 Decimal('sNaN') 197 >>> Decimal128(Decimal('-sNaN')).to_decimal() 198 Decimal('-sNaN') 199 200 Two instances of :class:`Decimal128` compare equal if their Binary 201 Integer Decimal encodings are equal:: 202 203 >>> Decimal128('NaN') == Decimal128('NaN') 204 True 205 >>> Decimal128('NaN').bid == Decimal128('NaN').bid 206 True 207 208 This differs from :class:`decimal.Decimal` comparisons for NaN:: 209 210 >>> Decimal('NaN') == Decimal('NaN') 211 False 212 """ 213 214 __slots__ = ("__high", "__low") 215 216 _type_marker = 19 217 218 def __init__(self, value): 219 if isinstance(value, (str, decimal.Decimal)): 220 self.__high, self.__low = _decimal_to_128(value) 221 elif isinstance(value, (list, tuple)): 222 if len(value) != 2: 223 raise ValueError( 224 "Invalid size for creation of Decimal128 " 225 "from list or tuple. Must have exactly 2 " 226 "elements." 227 ) 228 self.__high, self.__low = value 229 else: 230 raise TypeError("Cannot convert %r to Decimal128" % (value,)) 231 232 def to_decimal(self): 233 """Returns an instance of :class:`decimal.Decimal` for this 234 :class:`Decimal128`. 235 """ 236 high = self.__high 237 low = self.__low 238 sign = 1 if (high & _SIGN) else 0 239 240 if (high & _SNAN) == _SNAN: 241 return decimal.Decimal((sign, (), "N")) 242 elif (high & _NAN) == _NAN: 243 return decimal.Decimal((sign, (), "n")) 244 elif (high & _INF) == _INF: 245 return decimal.Decimal((sign, (), "F")) 246 247 if (high & _EXPONENT_MASK) == _EXPONENT_MASK: 248 exponent = ((high & 0x1FFFE00000000000) >> 47) - _EXPONENT_BIAS 249 return decimal.Decimal((sign, (0,), exponent)) 250 else: 251 exponent = ((high & 0x7FFF800000000000) >> 49) - _EXPONENT_BIAS 252 253 arr = bytearray(15) 254 mask = 0x00000000000000FF 255 for i in range(14, 6, -1): 256 arr[i] = (low & mask) >> ((14 - i) << 3) 257 mask = mask << 8 258 259 mask = 0x00000000000000FF 260 for i in range(6, 0, -1): 261 arr[i] = (high & mask) >> ((6 - i) << 3) 262 mask = mask << 8 263 264 mask = 0x0001000000000000 265 arr[0] = (high & mask) >> 48 266 267 # cdecimal only accepts a tuple for digits. 268 digits = tuple(int(digit) for digit in str(int.from_bytes(arr, "big"))) 269 270 with decimal.localcontext(_DEC128_CTX) as ctx: 271 return ctx.create_decimal((sign, digits, exponent)) 272 273 @classmethod 274 def from_bid(cls, value): 275 """Create an instance of :class:`Decimal128` from Binary Integer 276 Decimal string. 277 278 :Parameters: 279 - `value`: 16 byte string (128-bit IEEE 754-2008 decimal floating 280 point in Binary Integer Decimal (BID) format). 281 """ 282 if not isinstance(value, bytes): 283 raise TypeError("value must be an instance of bytes") 284 if len(value) != 16: 285 raise ValueError("value must be exactly 16 bytes") 286 return cls((_UNPACK_64(value[8:])[0], _UNPACK_64(value[:8])[0])) 287 288 @property 289 def bid(self): 290 """The Binary Integer Decimal (BID) encoding of this instance.""" 291 return _PACK_64(self.__low) + _PACK_64(self.__high) 292 293 def __str__(self): 294 dec = self.to_decimal() 295 if dec.is_nan(): 296 # Required by the drivers spec to match MongoDB behavior. 297 return "NaN" 298 return str(dec) 299 300 def __repr__(self): 301 return "Decimal128('%s')" % (str(self),) 302 303 def __setstate__(self, value): 304 self.__high, self.__low = value 305 306 def __getstate__(self): 307 return self.__high, self.__low 308 309 def __eq__(self, other): 310 if isinstance(other, Decimal128): 311 return self.bid == other.bid 312 return NotImplemented 313 314 def __ne__(self, other): 315 return not self == other
62def create_decimal128_context(): 63 """Returns an instance of :class:`decimal.Context` appropriate 64 for working with IEEE-754 128-bit decimal floating point values. 65 """ 66 opts = _CTX_OPTIONS.copy() 67 opts["traps"] = [] 68 return decimal.Context(**opts)
Returns an instance of decimal.Context
appropriate
for working with IEEE-754 128-bit decimal floating point values.
120class Decimal128(object): 121 """BSON Decimal128 type:: 122 123 >>> Decimal128(Decimal("0.0005")) 124 Decimal128('0.0005') 125 >>> Decimal128("0.0005") 126 Decimal128('0.0005') 127 >>> Decimal128((3474527112516337664, 5)) 128 Decimal128('0.0005') 129 130 :Parameters: 131 - `value`: An instance of :class:`decimal.Decimal`, string, or tuple of 132 (high bits, low bits) from Binary Integer Decimal (BID) format. 133 134 .. note:: :class:`~Decimal128` uses an instance of :class:`decimal.Context` 135 configured for IEEE-754 Decimal128 when validating parameters. 136 Signals like :class:`decimal.InvalidOperation`, :class:`decimal.Inexact`, 137 and :class:`decimal.Overflow` are trapped and raised as exceptions:: 138 139 >>> Decimal128(".13.1") 140 Traceback (most recent call last): 141 File "<stdin>", line 1, in <module> 142 ... 143 decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>] 144 >>> 145 >>> Decimal128("1E-6177") 146 Traceback (most recent call last): 147 File "<stdin>", line 1, in <module> 148 ... 149 decimal.Inexact: [<class 'decimal.Inexact'>] 150 >>> 151 >>> Decimal128("1E6145") 152 Traceback (most recent call last): 153 File "<stdin>", line 1, in <module> 154 ... 155 decimal.Overflow: [<class 'decimal.Overflow'>, <class 'decimal.Rounded'>] 156 157 To ensure the result of a calculation can always be stored as BSON 158 Decimal128 use the context returned by 159 :func:`create_decimal128_context`:: 160 161 >>> import decimal 162 >>> decimal128_ctx = create_decimal128_context() 163 >>> with decimal.localcontext(decimal128_ctx) as ctx: 164 ... Decimal128(ctx.create_decimal(".13.3")) 165 ... 166 Decimal128('NaN') 167 >>> 168 >>> with decimal.localcontext(decimal128_ctx) as ctx: 169 ... Decimal128(ctx.create_decimal("1E-6177")) 170 ... 171 Decimal128('0E-6176') 172 >>> 173 >>> with decimal.localcontext(DECIMAL128_CTX) as ctx: 174 ... Decimal128(ctx.create_decimal("1E6145")) 175 ... 176 Decimal128('Infinity') 177 178 To match the behavior of MongoDB's Decimal128 implementation 179 str(Decimal(value)) may not match str(Decimal128(value)) for NaN values:: 180 181 >>> Decimal128(Decimal('NaN')) 182 Decimal128('NaN') 183 >>> Decimal128(Decimal('-NaN')) 184 Decimal128('NaN') 185 >>> Decimal128(Decimal('sNaN')) 186 Decimal128('NaN') 187 >>> Decimal128(Decimal('-sNaN')) 188 Decimal128('NaN') 189 190 However, :meth:`~Decimal128.to_decimal` will return the exact value:: 191 192 >>> Decimal128(Decimal('NaN')).to_decimal() 193 Decimal('NaN') 194 >>> Decimal128(Decimal('-NaN')).to_decimal() 195 Decimal('-NaN') 196 >>> Decimal128(Decimal('sNaN')).to_decimal() 197 Decimal('sNaN') 198 >>> Decimal128(Decimal('-sNaN')).to_decimal() 199 Decimal('-sNaN') 200 201 Two instances of :class:`Decimal128` compare equal if their Binary 202 Integer Decimal encodings are equal:: 203 204 >>> Decimal128('NaN') == Decimal128('NaN') 205 True 206 >>> Decimal128('NaN').bid == Decimal128('NaN').bid 207 True 208 209 This differs from :class:`decimal.Decimal` comparisons for NaN:: 210 211 >>> Decimal('NaN') == Decimal('NaN') 212 False 213 """ 214 215 __slots__ = ("__high", "__low") 216 217 _type_marker = 19 218 219 def __init__(self, value): 220 if isinstance(value, (str, decimal.Decimal)): 221 self.__high, self.__low = _decimal_to_128(value) 222 elif isinstance(value, (list, tuple)): 223 if len(value) != 2: 224 raise ValueError( 225 "Invalid size for creation of Decimal128 " 226 "from list or tuple. Must have exactly 2 " 227 "elements." 228 ) 229 self.__high, self.__low = value 230 else: 231 raise TypeError("Cannot convert %r to Decimal128" % (value,)) 232 233 def to_decimal(self): 234 """Returns an instance of :class:`decimal.Decimal` for this 235 :class:`Decimal128`. 236 """ 237 high = self.__high 238 low = self.__low 239 sign = 1 if (high & _SIGN) else 0 240 241 if (high & _SNAN) == _SNAN: 242 return decimal.Decimal((sign, (), "N")) 243 elif (high & _NAN) == _NAN: 244 return decimal.Decimal((sign, (), "n")) 245 elif (high & _INF) == _INF: 246 return decimal.Decimal((sign, (), "F")) 247 248 if (high & _EXPONENT_MASK) == _EXPONENT_MASK: 249 exponent = ((high & 0x1FFFE00000000000) >> 47) - _EXPONENT_BIAS 250 return decimal.Decimal((sign, (0,), exponent)) 251 else: 252 exponent = ((high & 0x7FFF800000000000) >> 49) - _EXPONENT_BIAS 253 254 arr = bytearray(15) 255 mask = 0x00000000000000FF 256 for i in range(14, 6, -1): 257 arr[i] = (low & mask) >> ((14 - i) << 3) 258 mask = mask << 8 259 260 mask = 0x00000000000000FF 261 for i in range(6, 0, -1): 262 arr[i] = (high & mask) >> ((6 - i) << 3) 263 mask = mask << 8 264 265 mask = 0x0001000000000000 266 arr[0] = (high & mask) >> 48 267 268 # cdecimal only accepts a tuple for digits. 269 digits = tuple(int(digit) for digit in str(int.from_bytes(arr, "big"))) 270 271 with decimal.localcontext(_DEC128_CTX) as ctx: 272 return ctx.create_decimal((sign, digits, exponent)) 273 274 @classmethod 275 def from_bid(cls, value): 276 """Create an instance of :class:`Decimal128` from Binary Integer 277 Decimal string. 278 279 :Parameters: 280 - `value`: 16 byte string (128-bit IEEE 754-2008 decimal floating 281 point in Binary Integer Decimal (BID) format). 282 """ 283 if not isinstance(value, bytes): 284 raise TypeError("value must be an instance of bytes") 285 if len(value) != 16: 286 raise ValueError("value must be exactly 16 bytes") 287 return cls((_UNPACK_64(value[8:])[0], _UNPACK_64(value[:8])[0])) 288 289 @property 290 def bid(self): 291 """The Binary Integer Decimal (BID) encoding of this instance.""" 292 return _PACK_64(self.__low) + _PACK_64(self.__high) 293 294 def __str__(self): 295 dec = self.to_decimal() 296 if dec.is_nan(): 297 # Required by the drivers spec to match MongoDB behavior. 298 return "NaN" 299 return str(dec) 300 301 def __repr__(self): 302 return "Decimal128('%s')" % (str(self),) 303 304 def __setstate__(self, value): 305 self.__high, self.__low = value 306 307 def __getstate__(self): 308 return self.__high, self.__low 309 310 def __eq__(self, other): 311 if isinstance(other, Decimal128): 312 return self.bid == other.bid 313 return NotImplemented 314 315 def __ne__(self, other): 316 return not self == other
BSON Decimal128 type::
>>> Decimal128(Decimal("0.0005"))
Decimal128('0.0005')
>>> Decimal128("0.0005")
Decimal128('0.0005')
>>> Decimal128((3474527112516337664, 5))
Decimal128('0.0005')
:Parameters:
value
: An instance ofdecimal.Decimal
, string, or tuple of (high bits, low bits) from Binary Integer Decimal (BID) format.
~Decimal128
uses an instance of decimal.Context
configured for IEEE-754 Decimal128 when validating parameters.
Signals like decimal.InvalidOperation
, decimal.Inexact
,
and decimal.Overflow
are trapped and raised as exceptions::
>>> Decimal128(".13.1")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
...
decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]
>>>
>>> Decimal128("1E-6177")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
...
decimal.Inexact: [<class 'decimal.Inexact'>]
>>>
>>> Decimal128("1E6145")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
...
decimal.Overflow: [<class 'decimal.Overflow'>, <class 'decimal.Rounded'>]
To ensure the result of a calculation can always be stored as BSON
Decimal128 use the context returned by
create_decimal128_context()
::
>>> import decimal
>>> decimal128_ctx = create_decimal128_context()
>>> with decimal.localcontext(decimal128_ctx) as ctx:
... Decimal128(ctx.create_decimal(".13.3"))
...
Decimal128('NaN')
>>>
>>> with decimal.localcontext(decimal128_ctx) as ctx:
... Decimal128(ctx.create_decimal("1E-6177"))
...
Decimal128('0E-6176')
>>>
>>> with decimal.localcontext(DECIMAL128_CTX) as ctx:
... Decimal128(ctx.create_decimal("1E6145"))
...
Decimal128('Infinity')
To match the behavior of MongoDB's Decimal128 implementation str(Decimal(value)) may not match str(Decimal128(value)) for NaN values::
>>> Decimal128(Decimal('NaN'))
Decimal128('NaN')
>>> Decimal128(Decimal('-NaN'))
Decimal128('NaN')
>>> Decimal128(Decimal('sNaN'))
Decimal128('NaN')
>>> Decimal128(Decimal('-sNaN'))
Decimal128('NaN')
However, ~Decimal128.to_decimal()
will return the exact value::
>>> Decimal128(Decimal('NaN')).to_decimal()
Decimal('NaN')
>>> Decimal128(Decimal('-NaN')).to_decimal()
Decimal('-NaN')
>>> Decimal128(Decimal('sNaN')).to_decimal()
Decimal('sNaN')
>>> Decimal128(Decimal('-sNaN')).to_decimal()
Decimal('-sNaN')
Two instances of Decimal128
compare equal if their Binary
Integer Decimal encodings are equal::
>>> Decimal128('NaN') == Decimal128('NaN')
True
>>> Decimal128('NaN').bid == Decimal128('NaN').bid
True
This differs from decimal.Decimal
comparisons for NaN::
>>> Decimal('NaN') == Decimal('NaN')
False
219 def __init__(self, value): 220 if isinstance(value, (str, decimal.Decimal)): 221 self.__high, self.__low = _decimal_to_128(value) 222 elif isinstance(value, (list, tuple)): 223 if len(value) != 2: 224 raise ValueError( 225 "Invalid size for creation of Decimal128 " 226 "from list or tuple. Must have exactly 2 " 227 "elements." 228 ) 229 self.__high, self.__low = value 230 else: 231 raise TypeError("Cannot convert %r to Decimal128" % (value,))
233 def to_decimal(self): 234 """Returns an instance of :class:`decimal.Decimal` for this 235 :class:`Decimal128`. 236 """ 237 high = self.__high 238 low = self.__low 239 sign = 1 if (high & _SIGN) else 0 240 241 if (high & _SNAN) == _SNAN: 242 return decimal.Decimal((sign, (), "N")) 243 elif (high & _NAN) == _NAN: 244 return decimal.Decimal((sign, (), "n")) 245 elif (high & _INF) == _INF: 246 return decimal.Decimal((sign, (), "F")) 247 248 if (high & _EXPONENT_MASK) == _EXPONENT_MASK: 249 exponent = ((high & 0x1FFFE00000000000) >> 47) - _EXPONENT_BIAS 250 return decimal.Decimal((sign, (0,), exponent)) 251 else: 252 exponent = ((high & 0x7FFF800000000000) >> 49) - _EXPONENT_BIAS 253 254 arr = bytearray(15) 255 mask = 0x00000000000000FF 256 for i in range(14, 6, -1): 257 arr[i] = (low & mask) >> ((14 - i) << 3) 258 mask = mask << 8 259 260 mask = 0x00000000000000FF 261 for i in range(6, 0, -1): 262 arr[i] = (high & mask) >> ((6 - i) << 3) 263 mask = mask << 8 264 265 mask = 0x0001000000000000 266 arr[0] = (high & mask) >> 48 267 268 # cdecimal only accepts a tuple for digits. 269 digits = tuple(int(digit) for digit in str(int.from_bytes(arr, "big"))) 270 271 with decimal.localcontext(_DEC128_CTX) as ctx: 272 return ctx.create_decimal((sign, digits, exponent))
Returns an instance of decimal.Decimal
for this
Decimal128
.
274 @classmethod 275 def from_bid(cls, value): 276 """Create an instance of :class:`Decimal128` from Binary Integer 277 Decimal string. 278 279 :Parameters: 280 - `value`: 16 byte string (128-bit IEEE 754-2008 decimal floating 281 point in Binary Integer Decimal (BID) format). 282 """ 283 if not isinstance(value, bytes): 284 raise TypeError("value must be an instance of bytes") 285 if len(value) != 16: 286 raise ValueError("value must be exactly 16 bytes") 287 return cls((_UNPACK_64(value[8:])[0], _UNPACK_64(value[:8])[0]))
Create an instance of Decimal128
from Binary Integer
Decimal string.
:Parameters:
value
: 16 byte string (128-bit IEEE 754-2008 decimal floating point in Binary Integer Decimal (BID) format).