github.com/go-board/x-go@v0.1.2-0.20220610024734-db1323f6cb15/xsync/xatomic/atomic_float.go (about)

     1  package xatomic
     2  
     3  import (
     4  	"math"
     5  	"sync/atomic"
     6  )
     7  
     8  // AtomicFloat64 is an atomic wrapper around float64.
     9  type AtomicFloat64 struct {
    10  	v uint64
    11  }
    12  
    13  // NewAtomicFloat64 creates a AtomicFloat64.
    14  func NewAtomicFloat64(f float64) *AtomicFloat64 {
    15  	return &AtomicFloat64{math.Float64bits(f)}
    16  }
    17  
    18  // Load atomically loads the wrapped value.
    19  func (f *AtomicFloat64) Load() float64 {
    20  	return math.Float64frombits(atomic.LoadUint64(&f.v))
    21  }
    22  
    23  // Store atomically stores the passed value.
    24  func (f *AtomicFloat64) Store(s float64) {
    25  	atomic.StoreUint64(&f.v, math.Float64bits(s))
    26  }
    27  
    28  // Add atomically adds to the wrapped float64 and returns the new value.
    29  func (f *AtomicFloat64) Add(s float64) float64 {
    30  	for {
    31  		old := f.Load()
    32  		new := old + s
    33  		if f.CAS(old, new) {
    34  			return new
    35  		}
    36  	}
    37  }
    38  
    39  // Sub atomically subtracts from the wrapped float64 and returns the new value.
    40  func (f *AtomicFloat64) Sub(s float64) float64 {
    41  	return f.Add(-s)
    42  }
    43  
    44  // CAS is an atomic compare-and-swap.
    45  func (f *AtomicFloat64) CAS(old, new float64) bool {
    46  	return atomic.CompareAndSwapUint64(&f.v, math.Float64bits(old), math.Float64bits(new))
    47  }
    48  
    49  // AtomicFloat32 is an atomic wrapper around float32.
    50  type AtomicFloat32 struct {
    51  	v uint32
    52  }
    53  
    54  // NewAtomicFloat32 creates a AtomicFloat32.
    55  func NewAtomicFloat32(f float32) *AtomicFloat32 {
    56  	return &AtomicFloat32{math.Float32bits(f)}
    57  }
    58  
    59  // Load atomically loads the wrapped value.
    60  func (f *AtomicFloat32) Load() float32 {
    61  	return math.Float32frombits(atomic.LoadUint32(&f.v))
    62  }
    63  
    64  // Store atomically stores the passed value.
    65  func (f *AtomicFloat32) Store(s float32) {
    66  	atomic.StoreUint32(&f.v, math.Float32bits(s))
    67  }
    68  
    69  // Add atomically adds to the wrapped float32 and returns the new value.
    70  func (f *AtomicFloat32) Add(s float32) float32 {
    71  	for {
    72  		old := f.Load()
    73  		new := old + s
    74  		if f.CAS(old, new) {
    75  			return new
    76  		}
    77  	}
    78  }
    79  
    80  // Sub atomically subtracts from the wrapped float32 and returns the new value.
    81  func (f *AtomicFloat32) Sub(s float32) float32 {
    82  	return f.Add(-s)
    83  }
    84  
    85  // CAS is an atomic compare-and-swap.
    86  func (f *AtomicFloat32) CAS(old, new float32) bool {
    87  	return atomic.CompareAndSwapUint32(&f.v, math.Float32bits(old), math.Float32bits(new))
    88  }