github.com/gogf/gf@v1.16.9/container/gtype/float32.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  // Float32 is a struct for concurrent-safe operation for type float32.
    19  type Float32 struct {
    20  	value uint32
    21  }
    22  
    23  // NewFloat32 creates and returns a concurrent-safe object for float32 type,
    24  // with given initial value <value>.
    25  func NewFloat32(value ...float32) *Float32 {
    26  	if len(value) > 0 {
    27  		return &Float32{
    28  			value: math.Float32bits(value[0]),
    29  		}
    30  	}
    31  	return &Float32{}
    32  }
    33  
    34  // Clone clones and returns a new concurrent-safe object for float32 type.
    35  func (v *Float32) Clone() *Float32 {
    36  	return NewFloat32(v.Val())
    37  }
    38  
    39  // Set atomically stores <value> into t.value and returns the previous value of t.value.
    40  func (v *Float32) Set(value float32) (old float32) {
    41  	return math.Float32frombits(atomic.SwapUint32(&v.value, math.Float32bits(value)))
    42  }
    43  
    44  // Val atomically loads and returns t.value.
    45  func (v *Float32) Val() float32 {
    46  	return math.Float32frombits(atomic.LoadUint32(&v.value))
    47  }
    48  
    49  // Add atomically adds <delta> to t.value and returns the new value.
    50  func (v *Float32) Add(delta float32) (new float32) {
    51  	for {
    52  		old := math.Float32frombits(v.value)
    53  		new = old + delta
    54  		if atomic.CompareAndSwapUint32(
    55  			(*uint32)(unsafe.Pointer(&v.value)),
    56  			math.Float32bits(old),
    57  			math.Float32bits(new),
    58  		) {
    59  			break
    60  		}
    61  	}
    62  	return
    63  }
    64  
    65  // Cas executes the compare-and-swap operation for value.
    66  func (v *Float32) Cas(old, new float32) (swapped bool) {
    67  	return atomic.CompareAndSwapUint32(&v.value, math.Float32bits(old), math.Float32bits(new))
    68  }
    69  
    70  // String implements String interface for string printing.
    71  func (v *Float32) String() string {
    72  	return strconv.FormatFloat(float64(v.Val()), 'g', -1, 32)
    73  }
    74  
    75  // MarshalJSON implements the interface MarshalJSON for json.Marshal.
    76  func (v *Float32) MarshalJSON() ([]byte, error) {
    77  	return []byte(strconv.FormatFloat(float64(v.Val()), 'g', -1, 32)), nil
    78  }
    79  
    80  // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
    81  func (v *Float32) UnmarshalJSON(b []byte) error {
    82  	v.Set(gconv.Float32(string(b)))
    83  	return nil
    84  }
    85  
    86  // UnmarshalValue is an interface implement which sets any type of value for <v>.
    87  func (v *Float32) UnmarshalValue(value interface{}) error {
    88  	v.Set(gconv.Float32(value))
    89  	return nil
    90  }