This is what I tried (doesn’t work).
Int(floatNumber*1000.0)/1000.0
This is what I tried (doesn’t work).
Int(floatNumber*1000.0)/1000.0
There is the Ceil (up), Floor (down) and Round (nearest integer) function to round a number.
Thanks, I missed the whole “failable functions” part.
Round() only rounds to a whole number, what I need is to round to 3 decimal places.
Can you please give me an example?
Value = 6.456123456
and my desired output is 6.456 as float or as string (“6.456”).
Below is my attempt, when I divide the integer with 1000, and I get a rational type, and there is no way to convert a rational to either float or string.
var myFloatNumber : float = 6.456123456 * 1000.0
var myIntNumber : int = 0
var myFinalNumber : string = ""
if (Value := Round[myFloatNumber]):
set myIntNumber = Value
if (Value : rational = myIntNumber / 1000):
set myFinalNumber = ToString(Value)
Print(myFinalNumber)
This mostly comes down to a problem of converting between ints and floats in Verse. One thing you might have been missing is that you can multiply an int by 1.0 to turn it into a float. Here is a version of your original code with that + rounding integrated in.
QuickTest():logic =
if:
((Round[10.12345 * 1000.0] * 1.0) / 1000.0) = 10.123
then:
return true
else:
return false
I also gave a quick go at writing a more generic version
RoundToDecimalPlaces(Value:float, DecimalPlaces:int)<varies><decides>:float =
DecimalPlaces >= 0
Multiplier := Pow(10.0, DecimalPlaces * 1.0)
RoundedValues := Round[Value * Multiplier] * 1.0
return RoundedValues / Multiplier
QuickTest():logic =
if:
RoundToDecimalPlaces[10.12345, 0] = 10.0
RoundToDecimalPlaces[10.12345, 1] = 10.1
RoundToDecimalPlaces[10.12345, 2] = 10.12
RoundToDecimalPlaces[10.12345, 3] = 10.123
RoundToDecimalPlaces[10.12345, 4] = 10.1234
RoundToDecimalPlaces[10.12345, 5] = 10.12345
RoundToDecimalPlaces[10.12345, 6] = 10.123450
RoundToDecimalPlaces[10.56789, 0] = 11.0
RoundToDecimalPlaces[10.56789, 1] = 10.6
RoundToDecimalPlaces[10.56789, 2] = 10.57
RoundToDecimalPlaces[10.56789, 3] = 10.568
RoundToDecimalPlaces[10.56789, 4] = 10.5679
RoundToDecimalPlaces[10.56789, 5] = 10.56789
RoundToDecimalPlaces[10.56789, 6] = 10.56789
then:
return true
else:
return false
If you want to do it with a string, perhaps to show it on screen (ex. with a text_block widget), then here is a function I wrote that creates a string with a specified number of decimal places from a float.
GetRoundedString<private>(Input : float, NumDigitsAfterDecimal : int) : string =
if:
Multiplier := Pow(10.0, NumDigitsAfterDecimal * 1.0)
RoundedValue := RoundedTickRate := float[Round[Input*Multiplier]*1.0] / Multiplier
BeforeDecimal := Floor[RoundedValue]
AfterDecimal := Abs(Round[(RoundedValue - BeforeDecimal*1.0)*Multiplier])
var AfterDecimalString : string = ToString(AfterDecimal)
#pad with leading zeroes
for (It := 0..(NumDigitsAfterDecimal-AfterDecimalString.Length-1)):
set AfterDecimalString = array{'0'} + AfterDecimalString
then:
"{BeforeDecimal}.{AfterDecimalString}"
else:
ToString(Input)
This is fantastic, thanks for sharing!
Hello there,
Any idea on making this function working with negatives values ?
I mean im trying to round a big negative float (-13 800 000 000.0000) but when i apply the function it return me “-14.2 B” as a string obviously.
Honestly, i dont understand why it returns me this value
Im expecting to get “-13.8 B” and not “-14.2 B”
I tested it with positive value and its return the right value.
here is my code
RefreshUI(Agent:agent)<suspends>:void=
Print("Starting to Refresh")
if(TextBlock := ResourceTextBlockPerAgent[Agent]?):
loop:
Sleep(RefreshRate)
IncomeRateString: []char = ToString(incomeRate)
if (Wallet >= 1000000000.0 or Wallet <= -1000000000.0):
if(Wallet < 1000000000000.0 or Wallet > -1000000000000.0):
set WalletFloat = Wallet / 1000000000.0
set WalletString = GetRoundedString(WalletFloat, 1) + Billion
TextBlock.SetText(S2M("{WalletString} | {incomeRate}"))
else if (Wallet >= 1000000.0 or Wallet <= -1000000.0):
if(Wallet < 1000000000.0 or Wallet > -1000000000.0):
set WalletFloat = Wallet / 1000000.0
set WalletString = GetRoundedString(WalletFloat, 1) + Million
TextBlock.SetText(S2M("{WalletString} | {incomeRate}"))
else if (Wallet >= 1000.0 or Wallet <= -1000.0):
if(Wallet < 1000000.0 or Wallet > -1000000.0):
set WalletFloat = Wallet / 1000.0
set WalletString = GetRoundedString(WalletFloat, 1) + Kilo
TextBlock.SetText(S2M("{WalletString} | {incomeRate}"))
else if (Wallet < 1000.0 and Wallet > -1000.0):
set WalletFloat = Wallet
set WalletString = GetRoundedString(WalletFloat, 1)
TextBlock.SetText(S2M("{WalletString} | {incomeRate}"))
EDIT : i just found out on my UI that when my decimal is between 5 and 9, i will get this bug, but when my decimal is between 0 and 4 everything is working well.
So i think the problem is in the rounding method but idk how to solve that
Okay so I resolved my problem.
I had to use Ceil instead of Floor.
GetRoundedString(Input : float, NumDigitsAfterDecimal : int) : string =
if:
Multiplier := Pow(100.0, NumDigitsAfterDecimal * 1.0)
RoundedValue := RoundedTickRate := float[Ceil[Input*Multiplier]*1.0] / Multiplier
BeforeDecimal := Ceil[RoundedValue]
AfterDecimal := Abs(Ceil[(RoundedValue - BeforeDecimal*1.0)*Multiplier])
var AfterDecimalString : string = ToString(AfterDecimal)
#pad with leading zeroes
for (It := 0..(NumDigitsAfterDecimal-AfterDecimalString.Length-1)):
set AfterDecimalString = array{'0'} + AfterDecimalString
then:
"{BeforeDecimal}.{AfterDecimalString}"
else:
ToString(Input)