def _encode_number(self,sign,exp,integer,frac,byteorder="big",debug=False): assert isinstance(frac,list),\ "%s 'frac' argument must be a list: %s" \ % (fp.eloc(self,"_encode_number",module=this_module),frac) # Set the sign val = sign << self.sign_shift if __debug__: if debug: cls_str=fp.eloc(self,"_encode_number",module=this_module) print("%s sign: 0x%X" % (cls_str,val)) # Convert the significand into a list of digits if isinstance(frac,int): frac_lst=[frac,] else: frac_lst=frac prec=self.attr.prec-1 if len(frac_lst)<prec: zeros=prec-len(frac_lst) zeros=[0,]*zeros frac_lst.extend(zeros) elif len(frac_lst)>prec: frac_lst=frac_lst[:prec] frac_int=BFP_Formatter.bits2int(frac_lst) ifrac_int = frac_int & self.frac_mask if ifrac_int == 0 and exp == 0 and integer == 0: # This is a true zero value not a subnormal bexp = 0 if __debug__: if debug: print("%s signed exponent: %s" % (cls_str,exp)) print("%s biased exponent: %s" % (cls_str,bexp)) else: # Set the biased exponent bias = self.attr.bias bexp = exp + bias if __debug__: if debug: print("%s signed exponent: %s" % (cls_str,exp)) print("%s bias: %s" % (cls_str,bias)) print("%s biased exponent: %s" % (cls_str,bexp)) #print("%s exponent mask: 0x%X" % (cls_str,self.exp_msk)) val = val | bexp << self.exp_shift if __debug__: if debug: print("%s w/exp: 0x%X" % (cls_str,val)) # Set the significand val = val | ifrac_int if __debug__: if debug: print("%s coef: 0x%X" % (cls_str,frac_int)) print("%s w/coef:0x%X" % (cls_str,val)) # Convert to bytes return val.to_bytes(self.length,byteorder=byteorder,signed=False)
def __init__(self,byts): assert isinstance(byts,bytes),\ "%s 'byts' argument must be bytes: %s" \ % (fp.eloc(self,"__init__",module=this_module),byts) self.length=len(byts) try: dcdr=BFPRound.decode[self.length] except KeyError: raise ValueError("%s 'byts' argument must be of length 4, 8, or 16: %s"\ % (fp.eloc(self,"__init__",module=this_module),self.length)) sign,frac,exp,attr=dcdr.decode(attr,byts) super(),__init__(sign,frac,exp,attrs=attr)
def _encode_special(self, sign, signaling, payload, byteorder="big", debug=False): if __debug__: if debug: cls_str = fp.eloc(self, "_encode_special", module=this_module) print("%s sign:%s signaling:%s payload:%s byteorder:%s debug:%s"\ % (cls_str,sign,signaling,payload,byteorder,debug)) # Set the sign val = sign << self.sign_shift if __debug__: if debug: print("%s sign: 0x%X" % (cls_str, val)) # Set the reserved exponent value used by special values val = val | self.spec << self.exp_shift # Set the signaling value if not signaling: val = val | self.quiet_msk # Set the payload val = val | payload & self.payload_msk # Convert to bytes return val.to_bytes(self.length, byteorder=byteorder, signed=False)
def to_number(self,fpo): num=BFP_Number(fpo) if __debug__: if self.debug: print("%s BFP_Number - %s" \ % (fp.eloc(self,"number",module=this_module),lit)) return num
def __init__(self, src, ic=None, format=32, round=0, debug=False): self.ic = ic # Hexadecimal byte string of an external interchange format self.format = format # interchange format being created self.debug = debug # Remember debug status # Attributes related to the Python floating point object self.fpo = None # Python floating point object self.ctx = None # context associated with Python floating point object # These attributes are produced by the wrap() method that interprets the # Python floating point object self.isign = None # The value's sign self.integer = None # The implied integer value self.ibits = None # The actual bits destined for the significand self.iexp = None # The signed exponent destined for the biased exponent self.special = None # Special value to be set if isinstance(src, str): self.fpo = self.create(src, round=round) elif isinstance(src, self.__class__.cls): self.fpo = src else: raise ValueError("%s 'src' argument unrecognized: %s" \ % (fp.eloc(self,"__init__",module=this_module),src)) self.wrap() # Interpret the object for use by the framework
def __init__(self,src,ic=None,format=32,round=0,debug=False): self.ic=ic # Hexadecimal byte string of an external interchange format self.format=format # interchange format being created self.debug=debug # Remember debug status # Attributes related to the Python floating point object self.fpo=None # Python floating point object self.ctx=None # context associated with Python floating point object # These attributes are produced by the wrap() method that interprets the # Python floating point object self.isign=None # The value's sign self.integer=None # The implied integer value self.ibits=None # The actual bits destined for the significand self.iexp=None # The signed exponent destined for the biased exponent self.special=None # Special value to be set if isinstance(src,str): self.fpo=self.create(src,round=round) elif isinstance(src,self.__class__.cls): self.fpo=src else: raise ValueError("%s 'src' argument unrecognized: %s" \ % (fp.eloc(self,"__init__",module=this_module),src)) self.wrap() # Interpret the object for use by the framework
def wrap(self): self.digits,self.dexp,self.dprec=self.fpo.digits(2) # 2 is the base if __debug__: if self.debug: cls_str=fp.eloc(self,"wrap",module=this_module) print("%s digits: '%s'" % (cls_str,self.digits)) print("%s exp: %s" % (cls_str,self.dexp)) # Detect special values if self.digits == "-inf": self.isign=1 self.special="(inf)" self.overflow_detected return # Determine the sign of the value if self.digits[0] == "-": actual_digits=self.digits[1] self.isign=1 else: actual_digits=self.digits self.isign=0 if actual_digits=="0": # Handle the case of a true zero self.ibits=actual_digits self.integer="0" self.iexp=self.dexp else: # Handle the normal case self.ibits=actual_digits[1:] # Remove the implied first 1 self.integer=actual_digits[0] # The implied integer digit # The exponent assumes the leading one is part of the significand, so the # exponent is one larger than is required for the interchange format. self.iexp=self.dexp-1
def _decode_special(self,sign,digits,infinity,debug=False): if __debug__: if debug: cls_str=fp.eloc(self,"_decode_special",module=this_module) if infinity: bfp=BFP_Infinity(sign) else: # Must be a NaN then if digits[0]==0: signaling=True else: signaling=False payload_int = BFP_Formatter.bits2int(digits[1:]) if __debug__: if debug: print("%s found payload: %s" % (cls_str,payload_int)) if signaling: bfp=BFP_sNaN(sign,payload=payload_int) else: bfp=BFP_qNaN(sign,payload=payload_int) if __debug__: if debug: print("%s returning: %s" % (cls_str,bfp)) return bfp
def _encode_special(self,sign,signaling,payload,byteorder="big",debug=False): if __debug__: if debug: cls_str=fp.eloc(self,"_encode_special",module=this_module) print("%s sign:%s signaling:%s payload:%s byteorder:%s debug:%s"\ % (cls_str,sign,signaling,payload,byteorder,debug)) # Set the sign val = sign << self.sign_shift if __debug__: if debug: print("%s sign: 0x%X" % (cls_str,val)) # Set the reserved exponent value used by special values val = val | self.spec << self.exp_shift # Set the signaling value if not signaling: val = val | self.quiet_msk # Set the payload val = val | payload & self.payload_msk # Convert to bytes return val.to_bytes(self.length,byteorder=byteorder,signed=False)
def _decode_special(self, sign, digits, infinity, debug=False): if __debug__: if debug: cls_str = fp.eloc(self, "_decode_special", module=this_module) if infinity: bfp = BFP_Infinity(sign) else: # Must be a NaN then if digits[0] == 0: signaling = True else: signaling = False payload_int = BFP_Formatter.bits2int(digits[1:]) if __debug__: if debug: print("%s found payload: %s" % (cls_str, payload_int)) if signaling: bfp = BFP_sNaN(sign, payload=payload_int) else: bfp = BFP_qNaN(sign, payload=payload_int) if __debug__: if debug: print("%s returning: %s" % (cls_str, bfp)) return bfp
def decode(self,byts,prec=None,byteorder="big"): # Convert bytes to an integer fmt=int.from_bytes(byts,byteorder=byteorder,signed=False) # Extract the sign sign_bit = ( fmt & self.sign_msk ) >> self.sign_shift sign=sign_bit >> self.sign_shift # Extract the biased exponent and convert it to a signed exponent exp_bits = fmt & self.exp_msk exp=exp_bits >> self.exp_shift if exp == self.spec: raise fp.FPError(msg="%s BFP special can not be decoded as a number: %s" \ % (fp.eloc(self,"decode",module=this_module),fp.FP.bytes2str(byts))) exp = exp - self.bias # Extract the fraction frac_bits = fmt & self.frac_mask if prec is None: precision=self.attr.prec else: precision=prec base=self.attr.base if __debug__: # Perform sanity check to validate extraction was correct restored=sign_bit | exp_bits | frac_bits restored_byts=restored.to_bytes(len(byts),byteorder="big",signed=False) assert restored == fmt,\ "%s extracted fields do not match original fields:\n"\ " original: %s\m extracted: %s" \ % (fp.eloc(self,"decode",module=this_module),\ fp.bytes2str(byts),fp.bytes2str(restored_byts)) digits=[] fracwk=frac_bits for n in range(precision): fracwk,digit=divmod(fracwk,base) digits.append(digit) assert len(digits)==precision,\ "%s precision (%s) does not match number of digits produced: %s" \ % (fp.eloc(self,"decode",module=this_module),precision,len(digits)) digits.reverse() return (sign,digits,exp,self.attr)
def create(self): data=bfp.MPFR_Data(self.fpstr,format=self.length*8,round=self.rmodeo) if __debug__: if self.debug: print("%s %s" % (fp.eloc(self,"create",module=this_module),\ data.display(string=True))) return data
def to_bytes(self, length, byteorder="big", debug=False): ddebug = self.debug or debug try: format = BFP_Value.formatter[length] except KeyError: raise FPError(msg="%s 'length' argument must be 4, 8, or 16: %s" \ % (fp.eloc(self,"to_bytes",module=this_module),length)) return format.encode(self, byteorder=byteorder, debug=ddebug)
def to_bytes(self,length,byteorder="big",debug=False): ddebug=self.debug or debug try: format=BFP_Value.formatter[length] except KeyError: raise FPError(msg="%s 'length' argument must be 4, 8, or 16: %s" \ % (fp.eloc(self,"to_bytes",module=this_module),length)) return format.encode(self,byteorder=byteorder,debug=ddebug)
def encode(self, val, byteorder="big", debug=False): if isinstance(val, BFP_Finite): return self._encode_number(val.sign,val.exp,1,val.frac,\ byteorder=byteorder,debug=debug) elif isinstance(val, BFP_Special_Value): return self._encode_special(val.sign,val.signaling,val.payload,\ byteorder=byteorder,debug=debug) else: raise ValueError("%s 'val' argument must be a BFP_Value object: %s" \ % (fp.eloc(self,"encode",module=this_module),val))
def __init__(self, sign, payload=1, debug=False): assert payload != 0,\ "%s 'payload' argument must not be 0" \ % (fp.eloc(self,"__init__",module=this_module)) super().__init__(sign, "sNaN", signaling=True, payload=payload, debug=debug)
def __init__(self, sign, typ, signaling=False, payload=None, debug=False): assert payload >= 0,\ "%s 'payload' argument must not be negative: %s" \ % (fp.eloc(self,"__init__",module=this_module),payload) super().__init__(sign, typ, signaling=signaling, payload=payload, debug=debug)
def encode(self,val,byteorder="big",debug=False): if isinstance(val,BFP_Finite): return self._encode_number(val.sign,val.exp,1,val.frac,\ byteorder=byteorder,debug=debug) elif isinstance(val,BFP_Special_Value): return self._encode_special(val.sign,val.signaling,val.payload,\ byteorder=byteorder,debug=debug) else: raise ValueError("%s 'val' argument must be a BFP_Value object: %s" \ % (fp.eloc(self,"encode",module=this_module),val))
def __init__(self,src): if isinstance(src,float): s,e,f=self.float2number(src) elif isinstance(src,tuple) and len(src)==3: s,e,f=src else: raise ValueError(\ "%s 'src' must be either a float or tuple of length 3: %s" \ % (fp.eloc(self,"__init__",module=this_module),src)) super().__init__(s,e,f,2)
def __init__(self, src, ic=None, format=32, round=0, debug=False): assert gmpy2_available,\ "%s MPFR_Data must not be instantiated if the gmpy2 module is not "\ "available" % fp.eloc(self,"__init__",module=this_module) # These values are supplied by the gmpy2.mpfr.digits() method used by # the wrap() method self.digits = None # the binary digits of the signigicand as a string self.dexp = None # the signed exponent self.dprec = None # the precision of the object super().__init__(src, ic=ic, format=format, round=round, debug=debug)
def __init__(self,src,ic=None,format=32,round=0,debug=False): assert gmpy2_available,\ "%s MPFR_Data must not be instantiated if the gmpy2 module is not "\ "available" % fp.eloc(self,"__init__",module=this_module) # These values are supplied by the gmpy2.mpfr.digits() method used by # the wrap() method self.digits=None # the binary digits of the signigicand as a string self.dexp=None # the signed exponent self.dprec=None # the precision of the object super().__init__(src,ic=ic,format=format,round=round,debug=debug)
def create(self): if use_gmpy2: data=MPFR_Data(self.fpstr,format=self.length*8,round=self.rmodeo,\ debug=self.debug) else: data=FLOAT_Data(self.fpstr,format=self.length*8,debug=self.debug) if __debug__: if self.debug: print("%s %s" % (fp.eloc(self,"create",module=this_module),\ data.display(string=True))) return data
def create(self): if use_gmpy2: data=MPFR_Data(self.fpstr,format=self.length*8,round=self.rmodeo,\ debug=self.debug) else: data = FLOAT_Data(self.fpstr, format=self.length * 8, debug=self.debug) if __debug__: if self.debug: print("%s %s" % (fp.eloc(self,"create",module=this_module),\ data.display(string=True))) return data
def __init__(self,src): self.hx=None # Hex literal from float conversion self.mo=None # Regular expression match object from hex literal self.integer=None # Integer from parsed Hex literal if isinstance(src,float): s,e,f=self.float2number(src) elif isinstance(src,tuple) and len(src)==3: s,e,f=src else: raise ValueError(\ "%s 'src' must be either a float or tuple of length 3: %s" \ % (fp.eloc(self,"__init__",module=this_module),src)) super().__init__(s,e,f,2)
def wrap(self): self.hx=hx=self.fpo.hex() if __debug__: if self.debug: cls_str=fp.eloc(self,"wrap",module=this_module) print("%s hex: %s" % (cls_str,hx)) if hx == 'inf': if __debug__: if self.debug: print("%s positive infinity found" % cls_str) self.overflow_detected=True self.isign=0 self.special="(inf)" return elif hx == "-inf": if __debug__: if self.debug: print("%s negative infinity found" % cls_str) self.overflow_detected=True self.isign=1 self.special="-(inf)" return self.mo=mo=FLOAT_Data.parser.match(hx) if mo is None: raise ValueError("unrecognized hex literal: '%s'" % hx) mod=mo.groupdict() self.isign=FLOAT_Data.signs[mod["sign"]] integer=mod["integer"] if integer not in ["1","0"]: raise ValueError("unexpected integer in hex literal: '%s'" \ % self.integer) self.integer=int(integer) frac=mod["fraction"] frac=frac[1:] # Drop off the leading period of the fraction self.ibits=FLOAT_Data.hex2bin(frac) exp=mod["exp"] if exp is None: self.iexp=0 else: self.iexp=int(exp[1:],10)
def wrap(self): self.hx = hx = self.fpo.hex() if __debug__: if self.debug: cls_str = fp.eloc(self, "wrap", module=this_module) print("%s hex: %s" % (cls_str, hx)) if hx == 'inf': if __debug__: if self.debug: print("%s positive infinity found" % cls_str) self.overflow_detected = True self.isign = 0 self.special = "(inf)" return elif hx == "-inf": if __debug__: if self.debug: print("%s negative infinity found" % cls_str) self.overflow_detected = True self.isign = 1 self.special = "-(inf)" return self.mo = mo = FLOAT_Data.parser.match(hx) if mo is None: raise ValueError("unrecognized hex literal: '%s'" % hx) mod = mo.groupdict() self.isign = FLOAT_Data.signs[mod["sign"]] integer = mod["integer"] if integer not in ["1", "0"]: raise ValueError("unexpected integer in hex literal: '%s'" \ % self.integer) self.integer = int(integer) frac = mod["fraction"] frac = frac[1:] # Drop off the leading period of the fraction self.ibits = FLOAT_Data.hex2bin(frac) exp = mod["exp"] if exp is None: self.iexp = 0 else: self.iexp = int(exp[1:], 10)
def __init__(self,sign,integer=None,fraction=None,exp=0,rounding=12,\ format=None,debug=False): #assert isinstance(integer,str),\ # "%s 'integer' argument must be a string: %s" \ # % (fp.eloc(self,"__init__",module=this_module),integer) assert isinstance(format,BFP_Formatter),\ "%s 'attr' argument must be a BFP_Formatter object: %s" \ % (fp.eloc(self,"__init__",module=this_module),attr) self.formatter = format self.base = 2 self.integer = integer if isinstance(fraction, str): frac = self._str2list(fraction) else: frac = fraction super().__init__(sign,exp,frac,self.base,self.formatter.attr,\ rounding=rounding,debug=debug)
def __init__(self,sign,integer=None,fraction=None,exp=0,rounding=12,\ format=None,debug=False): #assert isinstance(integer,str),\ # "%s 'integer' argument must be a string: %s" \ # % (fp.eloc(self,"__init__",module=this_module),integer) assert isinstance(format,BFP_Formatter),\ "%s 'attr' argument must be a BFP_Formatter object: %s" \ % (fp.eloc(self,"__init__",module=this_module),attr) self.formatter=format self.base=2 self.integer=integer if isinstance(fraction,str): frac=self._str2list(fraction) else: frac=fraction super().__init__(sign,exp,frac,self.base,self.formatter.attr,\ rounding=rounding,debug=debug)
def __init__(self, src, ic=None, format=32, round=0): self.ic = ic # Interchange format hex data string self.fpo = None # gnoy2.mpfr object self.format = format # interchange format being created # These values are supplied by the gmpy2.mpfr.digits() method self.digits = None # the binary digits of the signigicand self.dexp = None # the signed exponent self.dprec = None # the precision of the object # These attributes are produced below and are destined for the interchange # format self.isign = None # The value's sign self.ibits = None # The actual bits destined for the significand self.iexp = None # The signed exponent destined for the int if isinstance(src, gmpy2.mpfr): self.fpo = src elif isinstance(src, str): ctx = gmpy2.ieee(format) ctx.round = gmpy2.round = round gmpy2.set_context(ctx) self.fpo = gmpy2.mpfr(src) else: raise ValueError( "%s 'byts' argument unrecognized: %s" % (fp.eloc(self, "__init__", module=this_module), byts) ) self.digits, self.dexp, self.dprec = self.fpo.digits(2) if self.digits[0] == "-": self.isign = 1 self.ibits = self.digits[2:] # Remove the sign and implied first 1 else: self.isign = 0 self.ibits = self.digits[1:] # Remove the implied first 1 # The exponent assumes the leading one is part of the significand, so the # exponent is one larger than is required for the interchange format. self.iexp = self.dexp - 1
def wrap(self): self.digits, self.dexp, self.dprec = self.fpo.digits( 2) # 2 is the base if __debug__: if self.debug: cls_str = fp.eloc(self, "wrap", module=this_module) print("%s digits: '%s'" % (cls_str, self.digits)) print("%s exp: %s" % (cls_str, self.dexp)) # Detect special values if self.digits == "-inf": self.isign = 1 self.special = "(inf)" self.overflow_detected return # Determine the sign of the value if self.digits[0] == "-": actual_digits = self.digits[1] self.isign = 1 else: actual_digits = self.digits self.isign = 0 if actual_digits == "0": # Handle the case of a true zero self.ibits = actual_digits self.integer = "0" self.iexp = self.dexp else: # Handle the normal case self.ibits = actual_digits[1:] # Remove the implied first 1 self.integer = actual_digits[0] # The implied integer digit # The exponent assumes the leading one is part of the significand, so the # exponent is one larger than is required for the interchange format. self.iexp = self.dexp - 1
def wrap(self): raise NotImplementedError("%s subclass %s must provide wrap() method" \ % (fp.eloc(self,"wrap",module=this_module),self.__class__.__name__))
def _encode_number(self, sign, exp, integer, frac, byteorder="big", debug=False): assert isinstance(frac,list),\ "%s 'frac' argument must be a list: %s" \ % (fp.eloc(self,"_encode_number",module=this_module),frac) # Set the sign val = sign << self.sign_shift if __debug__: if debug: cls_str = fp.eloc(self, "_encode_number", module=this_module) print("%s sign: 0x%X" % (cls_str, val)) # Convert the significand into a list of digits if isinstance(frac, int): frac_lst = [ frac, ] else: frac_lst = frac prec = self.attr.prec - 1 if len(frac_lst) < prec: zeros = prec - len(frac_lst) zeros = [ 0, ] * zeros frac_lst.extend(zeros) elif len(frac_lst) > prec: frac_lst = frac_lst[:prec] frac_int = BFP_Formatter.bits2int(frac_lst) ifrac_int = frac_int & self.frac_mask if ifrac_int == 0 and exp == 0 and integer == 0: # This is a true zero value not a subnormal bexp = 0 if __debug__: if debug: print("%s signed exponent: %s" % (cls_str, exp)) print("%s biased exponent: %s" % (cls_str, bexp)) else: # Set the biased exponent bias = self.attr.bias bexp = exp + bias if __debug__: if debug: print("%s signed exponent: %s" % (cls_str, exp)) print("%s bias: %s" % (cls_str, bias)) print("%s biased exponent: %s" % (cls_str, bexp)) #print("%s exponent mask: 0x%X" % (cls_str,self.exp_msk)) val = val | bexp << self.exp_shift if __debug__: if debug: print("%s w/exp: 0x%X" % (cls_str, val)) # Set the significand val = val | ifrac_int if __debug__: if debug: print("%s coef: 0x%X" % (cls_str, frac_int)) print("%s w/coef:0x%X" % (cls_str, val)) # Convert to bytes return val.to_bytes(self.length, byteorder=byteorder, signed=False)
def has_underflow(self): raise NotImplementedError("%s subclass %s must provide has_underflow() method"\ % (fp.eloc(self,"has_underflow",module=this_module),\ self.__class__.__name__))
def display(self, modes=False, indent="", string=False): raise NotImplementedError("%s subclass %s must provide display() method" \ % (fp.eloc(self,"display",module=this_module),self.__class__.__name__))
def display(self,modes=False,indent="",string=False): raise NotImplementedError("%s subclass %s must provide display() method" \ % (fp.eloc(self,"display",module=this_module),self.__class__.__name__))
def create(self,string,round=0): raise NotImplementedError("%s subclass %s must provide create() method" \ % (fp.eloc(self,"create",module=this_module),self.__class__.__name__))
def decode(self, byts, prec=None, byteorder="big", debug=False): # Convert bytes to an integer fmt = int.from_bytes(byts, byteorder=byteorder, signed=False) if __debug__: if debug: cls_str = fp.eloc(self, "decode", module=this_module) print("%s sign fld: 0x%X" % (cls_str, fmt)) # Extract the sign sign_fld = fmt & self.sign_msk if __debug__: if debug: print("%s sign field: 0x%X" % (cls_str, sign_fld)) sign = sign_fld >> self.sign_shift if __debug__: if debug: print("%s found sign: %s" % (cls_str, sign)) # Extract the biased exponent and convert it to a signed exponent exp_fld = fmt & self.exp_msk if __debug__: if debug: print("%s exp field: 0x%X" % (cls_str, exp_fld)) bexp = exp_fld >> self.exp_shift if __debug__: if debug: print("%s found bexp: %s" % (cls_str, bexp)) if bexp == self.spec: special = True if __debug__: if debug: print("%s found special value" % cls_str) else: exp = bexp - self.bias if __debug__: if debug: print("%s found finite number" % cls_str) print("%s found exp: %s" % (cls_str, exp)) special = False # Extract the fraction frac_fld = fmt & self.frac_mask if __debug__: if debug: print("%s frac mask: 0x%X" % (cls_str, self.frac_mask)) print("%s frac field: 0x%X" % (cls_str, frac_fld)) # Check for infinity if special and frac_fld == 0: infinity = True else: infinity = False if prec is None: precision = self.attr.prec else: precision = prec frac_prec = precision - 1 base = self.attr.base if __debug__: # Perform sanity check to validate extraction was correct restored = sign_fld | exp_fld | frac_fld restored_byts = restored.to_bytes(len(byts), byteorder="big", signed=False) assert restored == fmt,\ "%s extracted fields do not match original fields:\n"\ " original: %s\m extracted: %s" \ % (fp.eloc(self,"decode",module=this_module),\ fp.FP.bytes2str(byts),fp.FP.bytes2str(restored_byts)) digits = [] fracwk = frac_fld for n in range(frac_prec): fracwk, digit = divmod(fracwk, base) digits.append(digit) assert len(digits)==frac_prec,\ "%s precision (%s) does not match number of digits produced: %s" \ % (fp.eloc(self,"decode",module=this_module),precision,len(digits)) digits.reverse() if __debug__: if debug: print("%s found digits: %s" % (cls_str, digits)) if special: return self._decode_special(sign, digits, infinity, debug=debug) if bexp == 0: implied = 0 else: implied = 1 significand = [ implied, ] significand.extend(digits) if __debug__: if debug: print("%s found significand: %s" % (cls_str, significand)) return BFP_Finite(sign, exp, significand)
def __init__(self,sign,payload=1,debug=False): assert payload != 0,\ "%s 'payload' argument must not be 0" \ % (fp.eloc(self,"__init__",module=this_module)) super().__init__(sign,"sNaN",signaling=True,payload=payload,debug=debug)
def __init__(self,sign,typ,signaling=False,payload=None,debug=False): assert payload >= 0,\ "%s 'payload' argument must not be negative: %s" \ % (fp.eloc(self,"__init__",module=this_module),payload) super().__init__(sign,typ,signaling=signaling,payload=payload,debug=debug)
def to_number(self, fpo): data = MPFR_Data(fpo) raise NotImplementedError( "%s method implementation is incomplete" % fp.eloc(self, "to_number", module=this_module) )
def decode(self,byts,prec=None,byteorder="big",debug=False): # Convert bytes to an integer fmt=int.from_bytes(byts,byteorder=byteorder,signed=False) if __debug__: if debug: cls_str=fp.eloc(self,"decode",module=this_module) print("%s sign fld: 0x%X" % (cls_str,fmt)) # Extract the sign sign_fld = fmt & self.sign_msk if __debug__: if debug: print("%s sign field: 0x%X" % (cls_str,sign_fld)) sign=sign_fld >> self.sign_shift if __debug__: if debug: print("%s found sign: %s" % (cls_str,sign)) # Extract the biased exponent and convert it to a signed exponent exp_fld = fmt & self.exp_msk if __debug__: if debug: print("%s exp field: 0x%X" % (cls_str,exp_fld)) bexp=exp_fld >> self.exp_shift if __debug__: if debug: print("%s found bexp: %s" % (cls_str,bexp)) if bexp == self.spec: special=True if __debug__: if debug: print("%s found special value" % cls_str) else: exp = bexp - self.bias if __debug__: if debug: print("%s found finite number" % cls_str) print("%s found exp: %s" % (cls_str,exp)) special=False # Extract the fraction frac_fld = fmt & self.frac_mask if __debug__: if debug: print("%s frac mask: 0x%X" % (cls_str,self.frac_mask)) print("%s frac field: 0x%X" % (cls_str,frac_fld)) # Check for infinity if special and frac_fld==0: infinity=True else: infinity=False if prec is None: precision=self.attr.prec else: precision=prec frac_prec=precision-1 base=self.attr.base if __debug__: # Perform sanity check to validate extraction was correct restored=sign_fld | exp_fld | frac_fld restored_byts=restored.to_bytes(len(byts),byteorder="big",signed=False) assert restored == fmt,\ "%s extracted fields do not match original fields:\n"\ " original: %s\m extracted: %s" \ % (fp.eloc(self,"decode",module=this_module),\ fp.FP.bytes2str(byts),fp.FP.bytes2str(restored_byts)) digits=[] fracwk=frac_fld for n in range(frac_prec): fracwk,digit=divmod(fracwk,base) digits.append(digit) assert len(digits)==frac_prec,\ "%s precision (%s) does not match number of digits produced: %s" \ % (fp.eloc(self,"decode",module=this_module),precision,len(digits)) digits.reverse() if __debug__: if debug: print("%s found digits: %s" % (cls_str,digits)) if special: return self._decode_special(sign,digits,infinity,debug=debug) if bexp == 0: implied=0 else: implied=1 significand=[implied,] significand.extend(digits) if __debug__: if debug: print("%s found significand: %s" %(cls_str,significand)) return BFP_Finite(sign,exp,significand)
def create(self, string, round=0): raise NotImplementedError("%s subclass %s must provide create() method" \ % (fp.eloc(self,"create",module=this_module),self.__class__.__name__))