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 }