github.com/gogf/gf@v1.16.9/container/gtype/float64.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package gtype
     8  
     9  import (
    10  	"math"
    11  	"strconv"
    12  	"sync/atomic"
    13  	"unsafe"
    14  
    15  	"github.com/gogf/gf/util/gconv"
    16  )
    17  
    18  // Float64 is a struct for concurrent-safe operation for type float64.
    19  type Float64 struct {
    20  	value uint64
    21  }
    22  
    23  // NewFloat64 creates and returns a concurrent-safe object for float64 type,
    24  // with given initial value <value>.
    25  func NewFloat64(value ...float64) *Float64 {
    26  	if len(value) > 0 {
    27  		return &Float64{
    28  			value: math.Float64bits(value[0]),
    29  		}
    30  	}
    31  	return &Float64{}
    32  }
    33  
    34  // Clone clones and returns a new concurrent-safe object for float64 type.
    35  func (v *Float64) Clone() *Float64 {
    36  	return NewFloat64(v.Val())
    37  }
    38  
    39  // Set atomically stores <value> into t.value and returns the previous value of t.value.
    40  func (v *Float64) Set(value float64) (old float64) {
    41  	return math.Float64frombits(atomic.SwapUint64(&v.value, math.Float64bits(value)))
    42  }
    43  
    44  // Val atomically loads and returns t.value.
    45  func (v *Float64) Val() float64 {
    46  	return math.Float64frombits(atomic.LoadUint64(&v.value))
    47  }
    48  
    49  // Add atomically adds <delta> to t.value and returns the new value.
    50  func (v *Float64) Add(delta float64) (new float64) {
    51  	for {
    52  		old := math.Float64frombits(v.value)
    53  		new = old + delta
    54  		if atomic.CompareAndSwapUint64(
    55  			(*uint64)(unsafe.Pointer(&v.value)),
    56  			math.Float64bits(old),
    57  			math.Float64bits(new),
    58  		) {
    59  			break
    60  		}
    61  	}
    62  	return
    63  }
    64  
    65  // Cas executes the compare-and-swap operation for value.
    66  func (v *Float64) Cas(old, new float64) (swapped bool) {
    67  	return atomic.CompareAndSwapUint64(&v.value, math.Float64bits(old), math.Float64bits(new))
    68  }
    69  
    70  // String implements String interface for string printing.
    71  func (v *Float64) String() string {
    72  	return strconv.FormatFloat(v.Val(), 'g', -1, 64)
    73  }
    74  
    75  // MarshalJSON implements the interface MarshalJSON for json.Marshal.
    76  func (v *Float64) MarshalJSON() ([]byte, error) {
    77  	return []byte(strconv.FormatFloat(v.Val(), 'g', -1, 64)), nil
    78  }
    79  
    80  // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
    81  func (v *Float64) UnmarshalJSON(b []byte) error {
    82  	v.Set(gconv.Float64(string(b)))
    83  	return nil
    84  }
    85  
    86  // UnmarshalValue is an interface implement which sets any type of value for <v>.
    87  func (v *Float64) UnmarshalValue(value interface{}) error {
    88  	v.Set(gconv.Float64(value))
    89  	return nil
    90  }