ref #65, new formula function: CONVERT

This commit is contained in:
xuri 2022-04-20 00:01:39 +08:00
parent c2be30ce90
commit 81d9362b4f
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
2 changed files with 592 additions and 0 deletions

538
calc.go
View File

@ -58,6 +58,20 @@ const (
criteriaErr
criteriaRegexp
catgoryWeightAndMass
catgoryDistance
catgoryTime
catgoryPressure
catgoryForce
catgoryEnergy
catgoryPower
catgoryMagnetism
catgoryTemperature
catgoryVolumeAndLiquidMeasure
catgoryArea
catgoryInformation
catgorySpeed
matchModeExact = 0
matchModeMinGreater = 1
matchModeMaxLess = -1
@ -375,6 +389,7 @@ type formulaFuncs struct {
// CONFIDENCE
// CONFIDENCE.NORM
// CONFIDENCE.T
// CONVERT
// CORREL
// COS
// COSH
@ -2063,6 +2078,529 @@ func str2cmplx(c string) string {
return c
}
// conversionUnit defined unit info for conversion.
type conversionUnit struct {
group uint8
allowPrefix bool
}
// conversionUnits maps info list for unit conversion, that can be used in
// formula function CONVERT.
var conversionUnits = map[string]conversionUnit{
// weight and mass
"g": {group: catgoryWeightAndMass, allowPrefix: true},
"sg": {group: catgoryWeightAndMass, allowPrefix: false},
"lbm": {group: catgoryWeightAndMass, allowPrefix: false},
"u": {group: catgoryWeightAndMass, allowPrefix: true},
"ozm": {group: catgoryWeightAndMass, allowPrefix: false},
"grain": {group: catgoryWeightAndMass, allowPrefix: false},
"cwt": {group: catgoryWeightAndMass, allowPrefix: false},
"shweight": {group: catgoryWeightAndMass, allowPrefix: false},
"uk_cwt": {group: catgoryWeightAndMass, allowPrefix: false},
"lcwt": {group: catgoryWeightAndMass, allowPrefix: false},
"hweight": {group: catgoryWeightAndMass, allowPrefix: false},
"stone": {group: catgoryWeightAndMass, allowPrefix: false},
"ton": {group: catgoryWeightAndMass, allowPrefix: false},
"uk_ton": {group: catgoryWeightAndMass, allowPrefix: false},
"LTON": {group: catgoryWeightAndMass, allowPrefix: false},
"brton": {group: catgoryWeightAndMass, allowPrefix: false},
// distance
"m": {group: catgoryDistance, allowPrefix: true},
"mi": {group: catgoryDistance, allowPrefix: false},
"Nmi": {group: catgoryDistance, allowPrefix: false},
"in": {group: catgoryDistance, allowPrefix: false},
"ft": {group: catgoryDistance, allowPrefix: false},
"yd": {group: catgoryDistance, allowPrefix: false},
"ang": {group: catgoryDistance, allowPrefix: true},
"ell": {group: catgoryDistance, allowPrefix: false},
"ly": {group: catgoryDistance, allowPrefix: false},
"parsec": {group: catgoryDistance, allowPrefix: false},
"pc": {group: catgoryDistance, allowPrefix: false},
"Pica": {group: catgoryDistance, allowPrefix: false},
"Picapt": {group: catgoryDistance, allowPrefix: false},
"pica": {group: catgoryDistance, allowPrefix: false},
"survey_mi": {group: catgoryDistance, allowPrefix: false},
// time
"yr": {group: catgoryTime, allowPrefix: false},
"day": {group: catgoryTime, allowPrefix: false},
"d": {group: catgoryTime, allowPrefix: false},
"hr": {group: catgoryTime, allowPrefix: false},
"mn": {group: catgoryTime, allowPrefix: false},
"min": {group: catgoryTime, allowPrefix: false},
"sec": {group: catgoryTime, allowPrefix: true},
"s": {group: catgoryTime, allowPrefix: true},
// pressure
"Pa": {group: catgoryPressure, allowPrefix: true},
"p": {group: catgoryPressure, allowPrefix: true},
"atm": {group: catgoryPressure, allowPrefix: true},
"at": {group: catgoryPressure, allowPrefix: true},
"mmHg": {group: catgoryPressure, allowPrefix: true},
"psi": {group: catgoryPressure, allowPrefix: true},
"Torr": {group: catgoryPressure, allowPrefix: true},
// force
"N": {group: catgoryForce, allowPrefix: true},
"dyn": {group: catgoryForce, allowPrefix: true},
"dy": {group: catgoryForce, allowPrefix: true},
"lbf": {group: catgoryForce, allowPrefix: false},
"pond": {group: catgoryForce, allowPrefix: true},
// energy
"J": {group: catgoryEnergy, allowPrefix: true},
"e": {group: catgoryEnergy, allowPrefix: true},
"c": {group: catgoryEnergy, allowPrefix: true},
"cal": {group: catgoryEnergy, allowPrefix: true},
"eV": {group: catgoryEnergy, allowPrefix: true},
"ev": {group: catgoryEnergy, allowPrefix: true},
"HPh": {group: catgoryEnergy, allowPrefix: false},
"hh": {group: catgoryEnergy, allowPrefix: false},
"Wh": {group: catgoryEnergy, allowPrefix: true},
"wh": {group: catgoryEnergy, allowPrefix: true},
"flb": {group: catgoryEnergy, allowPrefix: false},
"BTU": {group: catgoryEnergy, allowPrefix: false},
"btu": {group: catgoryEnergy, allowPrefix: false},
// power
"HP": {group: catgoryPower, allowPrefix: false},
"h": {group: catgoryPower, allowPrefix: false},
"W": {group: catgoryPower, allowPrefix: true},
"w": {group: catgoryPower, allowPrefix: true},
"PS": {group: catgoryPower, allowPrefix: false},
"T": {group: catgoryMagnetism, allowPrefix: true},
"ga": {group: catgoryMagnetism, allowPrefix: true},
// temperature
"C": {group: catgoryTemperature, allowPrefix: false},
"cel": {group: catgoryTemperature, allowPrefix: false},
"F": {group: catgoryTemperature, allowPrefix: false},
"fah": {group: catgoryTemperature, allowPrefix: false},
"K": {group: catgoryTemperature, allowPrefix: false},
"kel": {group: catgoryTemperature, allowPrefix: false},
"Rank": {group: catgoryTemperature, allowPrefix: false},
"Reau": {group: catgoryTemperature, allowPrefix: false},
// volume
"l": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: true},
"L": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: true},
"lt": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: true},
"tsp": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"tspm": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"tbs": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"oz": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"cup": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"pt": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"us_pt": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"uk_pt": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"qt": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"uk_qt": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"gal": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"uk_gal": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"ang3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: true},
"ang^3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: true},
"barrel": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"bushel": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"in3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"in^3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"ft3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"ft^3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"ly3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"ly^3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"m3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: true},
"m^3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: true},
"mi3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"mi^3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"yd3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"yd^3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"Nmi3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"Nmi^3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"Pica3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"Pica^3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"Picapt3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"Picapt^3": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"GRT": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"regton": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
"MTON": {group: catgoryVolumeAndLiquidMeasure, allowPrefix: false},
// area
"ha": {group: catgoryArea, allowPrefix: true},
"uk_acre": {group: catgoryArea, allowPrefix: false},
"us_acre": {group: catgoryArea, allowPrefix: false},
"ang2": {group: catgoryArea, allowPrefix: true},
"ang^2": {group: catgoryArea, allowPrefix: true},
"ar": {group: catgoryArea, allowPrefix: true},
"ft2": {group: catgoryArea, allowPrefix: false},
"ft^2": {group: catgoryArea, allowPrefix: false},
"in2": {group: catgoryArea, allowPrefix: false},
"in^2": {group: catgoryArea, allowPrefix: false},
"ly2": {group: catgoryArea, allowPrefix: false},
"ly^2": {group: catgoryArea, allowPrefix: false},
"m2": {group: catgoryArea, allowPrefix: true},
"m^2": {group: catgoryArea, allowPrefix: true},
"Morgen": {group: catgoryArea, allowPrefix: false},
"mi2": {group: catgoryArea, allowPrefix: false},
"mi^2": {group: catgoryArea, allowPrefix: false},
"Nmi2": {group: catgoryArea, allowPrefix: false},
"Nmi^2": {group: catgoryArea, allowPrefix: false},
"Pica2": {group: catgoryArea, allowPrefix: false},
"Pica^2": {group: catgoryArea, allowPrefix: false},
"Picapt2": {group: catgoryArea, allowPrefix: false},
"Picapt^2": {group: catgoryArea, allowPrefix: false},
"yd2": {group: catgoryArea, allowPrefix: false},
"yd^2": {group: catgoryArea, allowPrefix: false},
// information
"byte": {group: catgoryInformation, allowPrefix: true},
"bit": {group: catgoryInformation, allowPrefix: true},
// speed
"m/s": {group: catgorySpeed, allowPrefix: true},
"m/sec": {group: catgorySpeed, allowPrefix: true},
"m/h": {group: catgorySpeed, allowPrefix: true},
"m/hr": {group: catgorySpeed, allowPrefix: true},
"mph": {group: catgorySpeed, allowPrefix: false},
"admkn": {group: catgorySpeed, allowPrefix: false},
"kn": {group: catgorySpeed, allowPrefix: false},
}
// unitConversions maps details of the Units of measure conversion factors,
// organised by group.
var unitConversions = map[byte]map[string]float64{
// conversion uses gram (g) as an intermediate unit
catgoryWeightAndMass: {
"g": 1,
"sg": 6.85217658567918e-05,
"lbm": 2.20462262184878e-03,
"u": 6.02214179421676e+23,
"ozm": 3.52739619495804e-02,
"grain": 1.54323583529414e+01,
"cwt": 2.20462262184878e-05,
"shweight": 2.20462262184878e-05,
"uk_cwt": 1.96841305522212e-05,
"lcwt": 1.96841305522212e-05,
"hweight": 1.96841305522212e-05,
"stone": 1.57473044417770e-04,
"ton": 1.10231131092439e-06,
"uk_ton": 9.84206527611061e-07,
"LTON": 9.84206527611061e-07,
"brton": 9.84206527611061e-07,
},
// conversion uses meter (m) as an intermediate unit
catgoryDistance: {
"m": 1,
"mi": 6.21371192237334e-04,
"Nmi": 5.39956803455724e-04,
"in": 3.93700787401575e+01,
"ft": 3.28083989501312e+00,
"yd": 1.09361329833771e+00,
"ang": 1.0e+10,
"ell": 8.74890638670166e-01,
"ly": 1.05700083402462e-16,
"parsec": 3.24077928966473e-17,
"pc": 3.24077928966473e-17,
"Pica": 2.83464566929134e+03,
"Picapt": 2.83464566929134e+03,
"pica": 2.36220472440945e+02,
"survey_mi": 6.21369949494950e-04,
},
// conversion uses second (s) as an intermediate unit
catgoryTime: {
"yr": 3.16880878140289e-08,
"day": 1.15740740740741e-05,
"d": 1.15740740740741e-05,
"hr": 2.77777777777778e-04,
"mn": 1.66666666666667e-02,
"min": 1.66666666666667e-02,
"sec": 1,
"s": 1,
},
// conversion uses Pascal (Pa) as an intermediate unit
catgoryPressure: {
"Pa": 1,
"p": 1,
"atm": 9.86923266716013e-06,
"at": 9.86923266716013e-06,
"mmHg": 7.50063755419211e-03,
"psi": 1.45037737730209e-04,
"Torr": 7.50061682704170e-03,
},
// conversion uses Newton (N) as an intermediate unit
catgoryForce: {
"N": 1,
"dyn": 1.0e+5,
"dy": 1.0e+5,
"lbf": 2.24808923655339e-01,
"pond": 1.01971621297793e+02,
},
// conversion uses Joule (J) as an intermediate unit
catgoryEnergy: {
"J": 1,
"e": 9.99999519343231e+06,
"c": 2.39006249473467e-01,
"cal": 2.38846190642017e-01,
"eV": 6.24145700000000e+18,
"ev": 6.24145700000000e+18,
"HPh": 3.72506430801000e-07,
"hh": 3.72506430801000e-07,
"Wh": 2.77777916238711e-04,
"wh": 2.77777916238711e-04,
"flb": 2.37304222192651e+01,
"BTU": 9.47815067349015e-04,
"btu": 9.47815067349015e-04,
},
// conversion uses Horsepower (HP) as an intermediate unit
catgoryPower: {
"HP": 1,
"h": 1,
"W": 7.45699871582270e+02,
"w": 7.45699871582270e+02,
"PS": 1.01386966542400e+00,
},
// conversion uses Tesla (T) as an intermediate unit
catgoryMagnetism: {
"T": 1,
"ga": 10000,
},
// conversion uses litre (l) as an intermediate unit
catgoryVolumeAndLiquidMeasure: {
"l": 1,
"L": 1,
"lt": 1,
"tsp": 2.02884136211058e+02,
"tspm": 2.0e+02,
"tbs": 6.76280454036860e+01,
"oz": 3.38140227018430e+01,
"cup": 4.22675283773038e+00,
"pt": 2.11337641886519e+00,
"us_pt": 2.11337641886519e+00,
"uk_pt": 1.75975398639270e+00,
"qt": 1.05668820943259e+00,
"uk_qt": 8.79876993196351e-01,
"gal": 2.64172052358148e-01,
"uk_gal": 2.19969248299088e-01,
"ang3": 1.0e+27,
"ang^3": 1.0e+27,
"barrel": 6.28981077043211e-03,
"bushel": 2.83775932584017e-02,
"in3": 6.10237440947323e+01,
"in^3": 6.10237440947323e+01,
"ft3": 3.53146667214886e-02,
"ft^3": 3.53146667214886e-02,
"ly3": 1.18093498844171e-51,
"ly^3": 1.18093498844171e-51,
"m3": 1.0e-03,
"m^3": 1.0e-03,
"mi3": 2.39912758578928e-13,
"mi^3": 2.39912758578928e-13,
"yd3": 1.30795061931439e-03,
"yd^3": 1.30795061931439e-03,
"Nmi3": 1.57426214685811e-13,
"Nmi^3": 1.57426214685811e-13,
"Pica3": 2.27769904358706e+07,
"Pica^3": 2.27769904358706e+07,
"Picapt3": 2.27769904358706e+07,
"Picapt^3": 2.27769904358706e+07,
"GRT": 3.53146667214886e-04,
"regton": 3.53146667214886e-04,
"MTON": 8.82866668037215e-04,
},
// conversion uses hectare (ha) as an intermediate unit
catgoryArea: {
"ha": 1,
"uk_acre": 2.47105381467165e+00,
"us_acre": 2.47104393046628e+00,
"ang2": 1.0e+24,
"ang^2": 1.0e+24,
"ar": 1.0e+02,
"ft2": 1.07639104167097e+05,
"ft^2": 1.07639104167097e+05,
"in2": 1.55000310000620e+07,
"in^2": 1.55000310000620e+07,
"ly2": 1.11725076312873e-28,
"ly^2": 1.11725076312873e-28,
"m2": 1.0e+04,
"m^2": 1.0e+04,
"Morgen": 4.0e+00,
"mi2": 3.86102158542446e-03,
"mi^2": 3.86102158542446e-03,
"Nmi2": 2.91553349598123e-03,
"Nmi^2": 2.91553349598123e-03,
"Pica2": 8.03521607043214e+10,
"Pica^2": 8.03521607043214e+10,
"Picapt2": 8.03521607043214e+10,
"Picapt^2": 8.03521607043214e+10,
"yd2": 1.19599004630108e+04,
"yd^2": 1.19599004630108e+04,
},
// conversion uses bit (bit) as an intermediate unit
catgoryInformation: {
"bit": 1,
"byte": 0.125,
},
// conversion uses Meters per Second (m/s) as an intermediate unit
catgorySpeed: {
"m/s": 1,
"m/sec": 1,
"m/h": 3.60e+03,
"m/hr": 3.60e+03,
"mph": 2.23693629205440e+00,
"admkn": 1.94260256941567e+00,
"kn": 1.94384449244060e+00,
},
}
// conversionMultipliers maps details of the Multiplier prefixes that can be
// used with Units of Measure in CONVERT.
var conversionMultipliers = map[string]float64{
"Y": 1e24,
"Z": 1e21,
"E": 1e18,
"P": 1e15,
"T": 1e12,
"G": 1e9,
"M": 1e6,
"k": 1e3,
"h": 1e2,
"e": 1e1,
"da": 1e1,
"d": 1e-1,
"c": 1e-2,
"m": 1e-3,
"u": 1e-6,
"n": 1e-9,
"p": 1e-12,
"f": 1e-15,
"a": 1e-18,
"z": 1e-21,
"y": 1e-24,
"Yi": math.Pow(2, 80),
"Zi": math.Pow(2, 70),
"Ei": math.Pow(2, 60),
"Pi": math.Pow(2, 50),
"Ti": math.Pow(2, 40),
"Gi": math.Pow(2, 30),
"Mi": math.Pow(2, 20),
"ki": math.Pow(2, 10),
}
// getUnitDetails check and returns the unit of measure details.
func getUnitDetails(uom string) (unit string, catgory byte, res float64, ok bool) {
if len(uom) == 0 {
ok = false
return
}
if unit, ok := conversionUnits[uom]; ok {
return uom, unit.group, 1, ok
}
// 1 character standard metric multiplier prefixes
multiplierType := uom[:1]
uom = uom[1:]
conversionUnit, ok1 := conversionUnits[uom]
multiplier, ok2 := conversionMultipliers[multiplierType]
if ok1 && ok2 {
if !conversionUnit.allowPrefix {
ok = false
return
}
unitCategory := conversionUnit.group
return uom, unitCategory, multiplier, true
}
// 2 character standard and binary metric multiplier prefixes
if len(uom) > 0 {
multiplierType += uom[:1]
uom = uom[1:]
}
conversionUnit, ok1 = conversionUnits[uom]
multiplier, ok2 = conversionMultipliers[multiplierType]
if ok1 && ok2 {
if !conversionUnit.allowPrefix {
ok = false
return
}
unitCategory := conversionUnit.group
return uom, unitCategory, multiplier, true
}
ok = false
return
}
// resolveTemperatureSynonyms returns unit of measure according to a given
// temperature synonyms.
func resolveTemperatureSynonyms(uom string) string {
switch uom {
case "fah":
return "F"
case "cel":
return "C"
case "kel":
return "K"
}
return uom
}
// convertTemperature returns converted temperature by a given unit of measure.
func convertTemperature(fromUOM, toUOM string, value float64) float64 {
fromUOM = resolveTemperatureSynonyms(fromUOM)
toUOM = resolveTemperatureSynonyms(toUOM)
if fromUOM == toUOM {
return value
}
// convert to Kelvin
switch fromUOM {
case "F":
value = (value-32)/1.8 + 273.15
break
case "C":
value += 273.15
break
case "Rank":
value /= 1.8
break
case "Reau":
value = value*1.25 + 273.15
break
}
// convert from Kelvin
switch toUOM {
case "F":
value = (value-273.15)*1.8 + 32
break
case "C":
value -= 273.15
break
case "Rank":
value *= 1.8
break
case "Reau":
value = (value - 273.15) * 0.8
break
}
return value
}
// CONVERT function converts a number from one unit type (e.g. Yards) to
// another unit type (e.g. Meters). The syntax of the function is:
//
// CONVERT(number,from_unit,to_unit)
//
func (fn *formulaFuncs) CONVERT(argsList *list.List) formulaArg {
if argsList.Len() != 3 {
return newErrorFormulaArg(formulaErrorVALUE, "CONVERT requires 3 arguments")
}
num := argsList.Front().Value.(formulaArg).ToNumber()
if num.Type != ArgNumber {
return num
}
fromUOM, fromCategory, fromMultiplier, ok1 := getUnitDetails(argsList.Front().Next().Value.(formulaArg).Value())
toUOM, toCategory, toMultiplier, ok2 := getUnitDetails(argsList.Back().Value.(formulaArg).Value())
if !ok1 || !ok2 || fromCategory != toCategory {
return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
}
val := num.Number * fromMultiplier
if fromUOM == toUOM && fromMultiplier == toMultiplier {
return newNumberFormulaArg(val / fromMultiplier)
} else if fromUOM == toUOM {
return newNumberFormulaArg(val / toMultiplier)
} else if fromCategory == catgoryTemperature {
return newNumberFormulaArg(convertTemperature(fromUOM, toUOM, val))
}
fromConversion, _ := unitConversions[fromCategory][fromUOM]
toConversion, _ := unitConversions[fromCategory][toUOM]
baseValue := val * (1 / fromConversion)
return newNumberFormulaArg((baseValue * toConversion) / toMultiplier)
}
// DEC2BIN function converts a decimal number into a Binary (Base 2) number.
// The syntax of the function is:
//

View File

@ -120,6 +120,45 @@ func TestCalcCellValue(t *testing.T) {
"=COMPLEX(0,-2)": "-2i",
"=COMPLEX(0,0)": "0",
"=COMPLEX(0,-1,\"j\")": "-j",
// CONVERT
"=CONVERT(20.2,\"m\",\"yd\")": "22.0909886264217",
"=CONVERT(20.2,\"cm\",\"yd\")": "0.220909886264217",
"=CONVERT(0.2,\"gal\",\"tsp\")": "153.6",
"=CONVERT(5,\"gal\",\"l\")": "18.92705892",
"=CONVERT(0.02,\"Gm\",\"m\")": "20000000",
"=CONVERT(0,\"C\",\"F\")": "32",
"=CONVERT(1,\"ly^2\",\"ly^2\")": "1",
"=CONVERT(0.00194255938572296,\"sg\",\"ozm\")": "1",
"=CONVERT(5,\"kg\",\"kg\")": "5",
"=CONVERT(4.5359237E-01,\"kg\",\"lbm\")": "1",
"=CONVERT(0.2,\"kg\",\"hg\")": "2",
"=CONVERT(12.345000000000001,\"km\",\"m\")": "12345",
"=CONVERT(12345,\"m\",\"km\")": "12.345",
"=CONVERT(0.621371192237334,\"mi\",\"km\")": "1",
"=CONVERT(1.23450000000000E+05,\"ang\",\"um\")": "12.345",
"=CONVERT(1.23450000000000E+02,\"kang\",\"um\")": "12.345",
"=CONVERT(1000,\"dal\",\"hl\")": "100",
"=CONVERT(1,\"yd\",\"ft\")": "2.99999999999999",
"=CONVERT(20,\"C\",\"F\")": "68",
"=CONVERT(68,\"F\",\"C\")": "20",
"=CONVERT(293.15,\"K\",\"F\")": "68",
"=CONVERT(68,\"F\",\"K\")": "293.15",
"=CONVERT(-273.15,\"C\",\"K\")": "0",
"=CONVERT(-459.67,\"F\",\"K\")": "0",
"=CONVERT(295.65,\"K\",\"C\")": "22.5",
"=CONVERT(22.5,\"C\",\"K\")": "295.65",
"=CONVERT(1667.85,\"C\",\"K\")": "1941",
"=CONVERT(3034.13,\"F\",\"K\")": "1941",
"=CONVERT(3493.8,\"Rank\",\"K\")": "1941",
"=CONVERT(1334.28,\"Reau\",\"K\")": "1941",
"=CONVERT(1941,\"K\",\"Rank\")": "3493.8",
"=CONVERT(1941,\"K\",\"Reau\")": "1334.28",
"=CONVERT(123.45,\"K\",\"kel\")": "123.45",
"=CONVERT(123.45,\"C\",\"cel\")": "123.45",
"=CONVERT(123.45,\"F\",\"fah\")": "123.45",
"=CONVERT(16,\"bit\",\"byte\")": "2",
"=CONVERT(1,\"kbyte\",\"byte\")": "1000",
"=CONVERT(1,\"kibyte\",\"byte\")": "1024",
// DEC2BIN
"=DEC2BIN(2)": "10",
"=DEC2BIN(3)": "11",
@ -2014,6 +2053,21 @@ func TestCalcCellValue(t *testing.T) {
"=COMPLEX(\"\",0)": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=COMPLEX(0,\"\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=COMPLEX(10,-5,\"i\",0)": "COMPLEX allows at most 3 arguments",
// CONVERT
"=CONVERT()": "CONVERT requires 3 arguments",
"=CONVERT(\"\",\"m\",\"yd\")": "strconv.ParseFloat: parsing \"\": invalid syntax",
"=CONVERT(20.2,\"m\",\"C\")": "#N/A",
"=CONVERT(20.2,\"\",\"C\")": "#N/A",
"=CONVERT(100,\"dapt\",\"pt\")": "#N/A",
"=CONVERT(1,\"ft\",\"day\")": "#N/A",
"=CONVERT(234.56,\"kpt\",\"lt\")": "#N/A",
"=CONVERT(234.56,\"lt\",\"kpt\")": "#N/A",
"=CONVERT(234.56,\"kiqt\",\"pt\")": "#N/A",
"=CONVERT(234.56,\"pt\",\"kiqt\")": "#N/A",
"=CONVERT(12345.6,\"baton\",\"cwt\")": "#N/A",
"=CONVERT(12345.6,\"cwt\",\"baton\")": "#N/A",
"=CONVERT(234.56,\"xxxx\",\"m\")": "#N/A",
"=CONVERT(234.56,\"m\",\"xxxx\")": "#N/A",
// DEC2BIN
"=DEC2BIN()": "DEC2BIN requires at least 1 argument",
"=DEC2BIN(1,1,1)": "DEC2BIN allows at most 2 arguments",