...

Source file src/github.com/cockroachdb/apd/v3/decomposer.go

Documentation: github.com/cockroachdb/apd/v3

     1  // Copyright 2016 The Cockroach Authors.
     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
    12  // implied. See the License for the specific language governing
    13  // permissions and limitations under the License.
    14  
    15  package apd
    16  
    17  import "fmt"
    18  
    19  // decomposer composes or decomposes a decimal value to and from individual parts.
    20  // There are four separate parts: a boolean negative flag, a form byte with three possible states
    21  // (finite=0, infinite=1, NaN=2),  a base-2 big-endian integer
    22  // coefficient (also known as a significand) as a []byte, and an int32 exponent.
    23  // These are composed into a final value as "decimal = (neg) (form=finite) coefficient * 10 ^ exponent".
    24  // A zero length coefficient is a zero value.
    25  // If the form is not finite the coefficient and scale should be ignored.
    26  // The negative parameter may be set to true for any form, although implementations are not required
    27  // to respect the negative parameter in the non-finite form.
    28  //
    29  // Implementations may choose to signal a negative zero or negative NaN, but implementations
    30  // that do not support these may also ignore the negative zero or negative NaN without error.
    31  // If an implementation does not support Infinity it may be converted into a NaN without error.
    32  // If a value is set that is larger then what is supported by an implementation is attempted to
    33  // be set, an error must be returned.
    34  // Implementations must return an error if a NaN or Infinity is attempted to be set while neither
    35  // are supported.
    36  type decomposer interface {
    37  	// Decompose returns the internal decimal state into parts.
    38  	// If the provided buf has sufficient capacity, buf may be returned as the coefficient with
    39  	// the value set and length set as appropriate.
    40  	Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32)
    41  
    42  	// Compose sets the internal decimal value from parts. If the value cannot be
    43  	// represented then an error should be returned.
    44  	// The coefficent should not be modified. Successive calls to compose with
    45  	// the same arguments should result in the same decimal value.
    46  	Compose(form byte, negative bool, coefficient []byte, exponent int32) error
    47  }
    48  
    49  var _ decomposer = &Decimal{}
    50  
    51  // Decompose returns the internal decimal state into parts.
    52  // If the provided buf has sufficient capacity, buf may be returned as the coefficient with
    53  // the value set and length set as appropriate.
    54  func (d *Decimal) Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32) {
    55  	switch d.Form {
    56  	default:
    57  		panic(fmt.Errorf("unknown Form: %v", d.Form))
    58  	case Finite:
    59  		// Nothing, continue on.
    60  	case Infinite:
    61  		negative = d.Negative
    62  		form = 1
    63  		return
    64  	case NaNSignaling, NaN:
    65  		negative = d.Negative
    66  		form = 2
    67  		return
    68  	}
    69  	// Finite form.
    70  	negative = d.Negative
    71  	exponent = d.Exponent
    72  	coefficient = d.Coeff.Bytes()
    73  	return
    74  }
    75  
    76  // Compose sets the internal decimal value from parts. If the value cannot be
    77  // represented then an error should be returned.
    78  func (d *Decimal) Compose(form byte, negative bool, coefficient []byte, exponent int32) error {
    79  	switch form {
    80  	default:
    81  		return fmt.Errorf("unknown form: %v", form)
    82  	case 0:
    83  		d.Form = Finite
    84  		// Set rest of finite form below.
    85  	case 1:
    86  		d.Form = Infinite
    87  		d.Negative = negative
    88  		return nil
    89  	case 2:
    90  		d.Form = NaN
    91  		d.Negative = negative
    92  		return nil
    93  	}
    94  	// Finite form.
    95  	d.Negative = negative
    96  	d.Coeff.SetBytes(coefficient)
    97  	d.Exponent = exponent
    98  	return nil
    99  }
   100  

View as plain text