1// Copieright (c) 2014 Couchbase, Inc. 2// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 3// except in compliance with the License. You may obtain a copy of the License at 4// http://www.apache.org/licenses/LICENSE-2.0 5// Unless required by applicable law or agreed to in writing, software distributed under the 6// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 7// either express or implied. See the License for the specific language governing permissions 8// and limitations under the License. 9 10package value 11 12import ( 13 "io" 14 "math" 15 "strconv" 16 17 "github.com/couchbase/query/util" 18) 19 20type floatValue float64 21 22var _NAN_BYTES = []byte("\"NaN\"") 23var _POS_INF_BYTES = []byte("\"+Infinity\"") 24var _NEG_INF_BYTES = []byte("\"-Infinity\"") 25 26func (this floatValue) String() string { 27 bytes, _ := this.MarshalJSON() 28 return string(bytes) 29} 30 31func (this floatValue) MarshalJSON() ([]byte, error) { 32 f := float64(this) 33 34 if math.IsNaN(f) { 35 return _NAN_BYTES, nil 36 } else if math.IsInf(f, 1) { 37 return _POS_INF_BYTES, nil 38 } else if math.IsInf(f, -1) { 39 return _NEG_INF_BYTES, nil 40 } else { 41 if f == -0 { 42 f = 0 43 } 44 45 s := strconv.FormatFloat(f, 'f', -1, 64) 46 return []byte(s), nil 47 } 48} 49 50func (this floatValue) WriteJSON(w io.Writer, prefix, indent string) error { 51 b, err := this.MarshalJSON() 52 if err != nil { 53 return err 54 } 55 _, err = w.Write(b) 56 return err 57} 58 59/* 60Type Number 61*/ 62func (this floatValue) Type() Type { 63 return NUMBER 64} 65 66func (this floatValue) Actual() interface{} { 67 return float64(this) 68} 69 70func (this floatValue) ActualForIndex() interface{} { 71 return float64(this) 72} 73 74func (this floatValue) Equals(other Value) Value { 75 other = other.unwrap() 76 switch other := other.(type) { 77 case missingValue: 78 return other 79 case *nullValue: 80 return other 81 case floatValue: 82 if this == other { 83 return TRUE_VALUE 84 } 85 case intValue: 86 if float64(this) == float64(other) { 87 return TRUE_VALUE 88 } 89 } 90 91 return FALSE_VALUE 92} 93 94func (this floatValue) EquivalentTo(other Value) bool { 95 other = other.unwrap() 96 switch other := other.(type) { 97 case floatValue: 98 return this == other 99 case intValue: 100 return float64(this) == float64(other) 101 default: 102 return false 103 } 104} 105 106func (this floatValue) Collate(other Value) int { 107 other = other.unwrap() 108 switch other := other.(type) { 109 case floatValue: 110 t := float64(this) 111 o := float64(other) 112 return collateFloat(t, o) 113 case intValue: 114 t := float64(this) 115 o := float64(other) 116 return collateFloat(t, o) 117 default: 118 return int(NUMBER - other.Type()) 119 } 120 121} 122 123func collateFloat(t, o float64) int { 124 // NaN sorts first 125 if math.IsNaN(t) { 126 if math.IsNaN(o) { 127 return 0 128 } else { 129 return -1 130 } 131 } 132 133 if math.IsNaN(o) { 134 return 1 135 } 136 137 // NegInfinity sorts next 138 if math.IsInf(t, -1) { 139 if math.IsInf(o, -1) { 140 return 0 141 } else { 142 return -1 143 } 144 } 145 146 if math.IsInf(o, -1) { 147 return 1 148 } 149 150 // PosInfinity sorts last 151 if math.IsInf(t, 1) { 152 if math.IsInf(o, 1) { 153 return 0 154 } else { 155 return 1 156 } 157 } 158 159 if math.IsInf(o, 1) { 160 return -1 161 } 162 163 result := t - o 164 switch { 165 case result < 0.0: 166 return -1 167 case result > 0.0: 168 return 1 169 default: 170 return 0 171 } 172} 173 174func (this floatValue) Compare(other Value) Value { 175 other = other.unwrap() 176 switch other := other.(type) { 177 case missingValue: 178 return other 179 case *nullValue: 180 return other 181 default: 182 return intValue(this.Collate(other)) 183 } 184} 185 186/* 187Returns true in the event the receiver is not 0 and it isn’t 188a NaN value 189*/ 190func (this floatValue) Truth() bool { 191 return !math.IsNaN(float64(this)) && this != 0 192} 193 194/* 195Return receiver 196*/ 197func (this floatValue) Copy() Value { 198 return this 199} 200 201/* 202Return receiver 203*/ 204func (this floatValue) CopyForUpdate() Value { 205 return this 206} 207 208/* 209Calls missingField. 210*/ 211func (this floatValue) Field(field string) (Value, bool) { 212 return missingField(field), false 213} 214 215/* 216Not valid for NUMBER. 217*/ 218func (this floatValue) SetField(field string, val interface{}) error { 219 return Unsettable(field) 220} 221 222/* 223Not valid for NUMBER. 224*/ 225func (this floatValue) UnsetField(field string) error { 226 return Unsettable(field) 227} 228 229/* 230Calls missingIndex. 231*/ 232func (this floatValue) Index(index int) (Value, bool) { 233 return missingIndex(index), false 234} 235 236/* 237Not valid for NUMBER. 238*/ 239func (this floatValue) SetIndex(index int, val interface{}) error { 240 return Unsettable(index) 241} 242 243/* 244Returns NULL_VALUE 245*/ 246func (this floatValue) Slice(start, end int) (Value, bool) { 247 return NULL_VALUE, false 248} 249 250/* 251Returns NULL_VALUE 252*/ 253func (this floatValue) SliceTail(start int) (Value, bool) { 254 return NULL_VALUE, false 255} 256 257/* 258Returns the input buffer as is. 259*/ 260func (this floatValue) Descendants(buffer []interface{}) []interface{} { 261 return buffer 262} 263 264/* 265As number has no fields, return nil. 266*/ 267func (this floatValue) Fields() map[string]interface{} { 268 return nil 269} 270 271func (this floatValue) FieldNames(buffer []string) []string { 272 return nil 273} 274 275/* 276Returns the input buffer as is. 277*/ 278func (this floatValue) DescendantPairs(buffer []util.IPair) []util.IPair { 279 return buffer 280} 281 282/* 283Obey N1QL collation order for numbers. After that, NUMBER is succeeded 284by STRING. 285*/ 286func (this floatValue) Successor() Value { 287 // NaN sorts lowest 288 t := float64(this) 289 290 if math.IsNaN(t) { 291 return floatValue(math.Inf(-1)) 292 } 293 294 // -Inf sorts next 295 if math.IsInf(t, -1) { 296 return floatValue(-math.MaxFloat64) 297 } 298 299 // +Inf sorts last 300 if math.IsInf(t, 1) || this >= math.MaxFloat64 { 301 return EMPTY_STRING_VALUE 302 } 303 304 return floatValue(math.Nextafter(t, math.MaxFloat64)) 305} 306 307func (this floatValue) Recycle() { 308} 309 310func (this floatValue) Tokens(set *Set, options Value) *Set { 311 set.Add(this) 312 return set 313} 314 315func (this floatValue) ContainsToken(token, options Value) bool { 316 return this.EquivalentTo(token) 317} 318 319func (this floatValue) ContainsMatchingToken(matcher MatchFunc, options Value) bool { 320 return matcher(float64(this)) 321} 322 323func (this floatValue) unwrap() Value { 324 return this 325} 326 327/* 328NumberValue methods. 329*/ 330 331func (this floatValue) Add(n NumberValue) NumberValue { 332 return floatValue(float64(this) + n.Actual().(float64)) 333} 334 335func (this floatValue) IDiv(n NumberValue) Value { 336 switch n := n.(type) { 337 case intValue: 338 if n == 0 { 339 return NULL_VALUE 340 } else { 341 return intValue(this) / n 342 } 343 default: 344 f := n.Actual().(float64) 345 if f == 0.0 { 346 return NULL_VALUE 347 } else { 348 return intValue(int64(this) / int64(f)) 349 } 350 } 351} 352 353func (this floatValue) IMod(n NumberValue) Value { 354 switch n := n.(type) { 355 case intValue: 356 if n == 0 { 357 return NULL_VALUE 358 } else { 359 return intValue(this) % n 360 } 361 default: 362 f := n.Actual().(float64) 363 if f == 0.0 { 364 return NULL_VALUE 365 } else { 366 return intValue(int64(this) % int64(f)) 367 } 368 } 369} 370 371func (this floatValue) Mult(n NumberValue) NumberValue { 372 return floatValue(float64(this) * n.Actual().(float64)) 373} 374 375func (this floatValue) Neg() NumberValue { 376 return -this 377} 378 379func (this floatValue) Sub(n NumberValue) NumberValue { 380 return floatValue(float64(this) - n.Actual().(float64)) 381} 382 383func (this floatValue) Int64() int64 { 384 return int64(this) 385} 386