@@ -1294,6 +1294,78 @@ func TestNegateRoundTrip(t *testing.T) {
1294
1294
}
1295
1295
1296
1296
func TestQuantityAsApproximateFloat64 (t * testing.T ) {
1297
+ // NOTE: this table should be kept in sync with TestQuantityAsFloat64Slow
1298
+ table := []struct {
1299
+ in Quantity
1300
+ out float64
1301
+ }{
1302
+ {decQuantity (0 , 0 , DecimalSI ), 0.0 },
1303
+ {decQuantity (0 , 0 , DecimalExponent ), 0.0 },
1304
+ {decQuantity (0 , 0 , BinarySI ), 0.0 },
1305
+
1306
+ {decQuantity (1 , 0 , DecimalSI ), 1 },
1307
+ {decQuantity (1 , 0 , DecimalExponent ), 1 },
1308
+ {decQuantity (1 , 0 , BinarySI ), 1 },
1309
+
1310
+ // Binary suffixes
1311
+ {decQuantity (1024 , 0 , BinarySI ), 1024 },
1312
+ {decQuantity (8 * 1024 , 0 , BinarySI ), 8 * 1024 },
1313
+ {decQuantity (7 * 1024 * 1024 , 0 , BinarySI ), 7 * 1024 * 1024 },
1314
+ {decQuantity (7 * 1024 * 1024 , 1 , BinarySI ), (7 * 1024 * 1024 ) * 10 },
1315
+ {decQuantity (7 * 1024 * 1024 , 4 , BinarySI ), (7 * 1024 * 1024 ) * 10000 },
1316
+ {decQuantity (7 * 1024 * 1024 , 8 , BinarySI ), (7 * 1024 * 1024 ) * 100000000 },
1317
+ {decQuantity (7 * 1024 * 1024 , - 1 , BinarySI ), (7 * 1024 * 1024 ) * math .Pow10 (- 1 )}, // '* Pow10' and '/ float(10)' do not round the same way
1318
+ {decQuantity (7 * 1024 * 1024 , - 8 , BinarySI ), (7 * 1024 * 1024 ) / float64 (100000000 )},
1319
+
1320
+ {decQuantity (1024 , 0 , DecimalSI ), 1024 },
1321
+ {decQuantity (8 * 1024 , 0 , DecimalSI ), 8 * 1024 },
1322
+ {decQuantity (7 * 1024 * 1024 , 0 , DecimalSI ), 7 * 1024 * 1024 },
1323
+ {decQuantity (7 * 1024 * 1024 , 1 , DecimalSI ), (7 * 1024 * 1024 ) * 10 },
1324
+ {decQuantity (7 * 1024 * 1024 , 4 , DecimalSI ), (7 * 1024 * 1024 ) * 10000 },
1325
+ {decQuantity (7 * 1024 * 1024 , 8 , DecimalSI ), (7 * 1024 * 1024 ) * 100000000 },
1326
+ {decQuantity (7 * 1024 * 1024 , - 1 , DecimalSI ), (7 * 1024 * 1024 ) * math .Pow10 (- 1 )}, // '* Pow10' and '/ float(10)' do not round the same way
1327
+ {decQuantity (7 * 1024 * 1024 , - 8 , DecimalSI ), (7 * 1024 * 1024 ) / float64 (100000000 )},
1328
+
1329
+ {decQuantity (1024 , 0 , DecimalExponent ), 1024 },
1330
+ {decQuantity (8 * 1024 , 0 , DecimalExponent ), 8 * 1024 },
1331
+ {decQuantity (7 * 1024 * 1024 , 0 , DecimalExponent ), 7 * 1024 * 1024 },
1332
+ {decQuantity (7 * 1024 * 1024 , 1 , DecimalExponent ), (7 * 1024 * 1024 ) * 10 },
1333
+ {decQuantity (7 * 1024 * 1024 , 4 , DecimalExponent ), (7 * 1024 * 1024 ) * 10000 },
1334
+ {decQuantity (7 * 1024 * 1024 , 8 , DecimalExponent ), (7 * 1024 * 1024 ) * 100000000 },
1335
+ {decQuantity (7 * 1024 * 1024 , - 1 , DecimalExponent ), (7 * 1024 * 1024 ) * math .Pow10 (- 1 )}, // '* Pow10' and '/ float(10)' do not round the same way
1336
+ {decQuantity (7 * 1024 * 1024 , - 8 , DecimalExponent ), (7 * 1024 * 1024 ) / float64 (100000000 )},
1337
+
1338
+ // very large numbers
1339
+ {Quantity {d : maxAllowed , Format : DecimalSI }, math .MaxInt64 },
1340
+ {Quantity {d : maxAllowed , Format : BinarySI }, math .MaxInt64 },
1341
+ {decQuantity (12 , 18 , DecimalSI ), 1.2e19 },
1342
+
1343
+ // infinities caused due to float64 overflow
1344
+ {decQuantity (12 , 500 , DecimalSI ), math .Inf (0 )},
1345
+ {decQuantity (- 12 , 500 , DecimalSI ), math .Inf (- 1 )},
1346
+ }
1347
+
1348
+ for i , item := range table {
1349
+ t .Run (fmt .Sprintf ("%s %s" , item .in .Format , item .in .String ()), func (t * testing.T ) {
1350
+ out := item .in .AsApproximateFloat64 ()
1351
+ if out != item .out {
1352
+ t .Fatalf ("test %d expected %v, got %v" , i + 1 , item .out , out )
1353
+ }
1354
+ if item .in .d .Dec != nil {
1355
+ if i , ok := item .in .AsInt64 (); ok {
1356
+ q := intQuantity (i , 0 , item .in .Format )
1357
+ out := q .AsApproximateFloat64 ()
1358
+ if out != item .out {
1359
+ t .Fatalf ("as int quantity: expected %v, got %v" , item .out , out )
1360
+ }
1361
+ }
1362
+ }
1363
+ })
1364
+ }
1365
+ }
1366
+
1367
+ func TestQuantityAsFloat64Slow (t * testing.T ) {
1368
+ // NOTE: this table should be kept in sync with TestQuantityAsApproximateFloat64
1297
1369
table := []struct {
1298
1370
in Quantity
1299
1371
out float64
@@ -1346,14 +1418,14 @@ func TestQuantityAsApproximateFloat64(t *testing.T) {
1346
1418
1347
1419
for i , item := range table {
1348
1420
t .Run (fmt .Sprintf ("%s %s" , item .in .Format , item .in .String ()), func (t * testing.T ) {
1349
- out := item .in .AsApproximateFloat64 ()
1421
+ out := item .in .AsFloat64Slow ()
1350
1422
if out != item .out {
1351
1423
t .Fatalf ("test %d expected %v, got %v" , i + 1 , item .out , out )
1352
1424
}
1353
1425
if item .in .d .Dec != nil {
1354
1426
if i , ok := item .in .AsInt64 (); ok {
1355
1427
q := intQuantity (i , 0 , item .in .Format )
1356
- out := q .AsApproximateFloat64 ()
1428
+ out := q .AsFloat64Slow ()
1357
1429
if out != item .out {
1358
1430
t .Fatalf ("as int quantity: expected %v, got %v" , item .out , out )
1359
1431
}
@@ -1397,6 +1469,40 @@ func TestStringQuantityAsApproximateFloat64(t *testing.T) {
1397
1469
}
1398
1470
}
1399
1471
1472
+ func TestStringQuantityAsFloat64Slow (t * testing.T ) {
1473
+ table := []struct {
1474
+ in string
1475
+ out float64
1476
+ }{
1477
+ {"2Ki" , 2048 },
1478
+ {"1.1Ki" , 1126.4e+0 },
1479
+ {"1Mi" , 1.048576e+06 },
1480
+ {"2Gi" , 2.147483648e+09 },
1481
+ }
1482
+
1483
+ for _ , item := range table {
1484
+ t .Run (item .in , func (t * testing.T ) {
1485
+ in , err := ParseQuantity (item .in )
1486
+ if err != nil {
1487
+ t .Fatal (err )
1488
+ }
1489
+ out := in .AsFloat64Slow ()
1490
+ if out != item .out {
1491
+ t .Fatalf ("expected %v, got %v" , item .out , out )
1492
+ }
1493
+ if in .d .Dec != nil {
1494
+ if i , ok := in .AsInt64 (); ok {
1495
+ q := intQuantity (i , 0 , in .Format )
1496
+ out := q .AsFloat64Slow ()
1497
+ if out != item .out {
1498
+ t .Fatalf ("as int quantity: expected %v, got %v" , item .out , out )
1499
+ }
1500
+ }
1501
+ }
1502
+ })
1503
+ }
1504
+ }
1505
+
1400
1506
func benchmarkQuantities () []Quantity {
1401
1507
return []Quantity {
1402
1508
intQuantity (1024 * 1024 * 1024 , 0 , BinarySI ),
@@ -1579,6 +1685,18 @@ func BenchmarkQuantityAsApproximateFloat64(b *testing.B) {
1579
1685
b .StopTimer ()
1580
1686
}
1581
1687
1688
+ func BenchmarkQuantityAsFloat64Slow (b * testing.B ) {
1689
+ values := benchmarkQuantities ()
1690
+ b .ResetTimer ()
1691
+ for i := 0 ; i < b .N ; i ++ {
1692
+ q := values [i % len (values )]
1693
+ if q .AsFloat64Slow () == - 1 {
1694
+ b .Fatal (q )
1695
+ }
1696
+ }
1697
+ b .StopTimer ()
1698
+ }
1699
+
1582
1700
var _ pflag.Value = & QuantityValue {}
1583
1701
1584
1702
func TestQuantityValueSet (t * testing.T ) {
0 commit comments