I was trying to make a MsgBox look nice yet have the most accurate values, and I came up with this. It makes it nice because if you have a variable that may or may not have a decimal value, it can be annoying to see the extra zeros. This will make it an integer if there are no decimal values, or add them up to the final stored value if they are there.
I added the comments to most of the lines, so it should be pretty self explanatory. Also, if someone has already come up with this before, my bad. I had been searching and couldn't find anything anywhere.
var1 := 15.372000 ; This is the variable from which you want to cut out the trailing zeros testVar1 := var1 ; This is a copy to preserve the original rCheck := mod(var1, 2) ; This is the value we will be testing against Loop 12 ; The loop count should be 1 + the maximum number of decimal digits you expect to see but higher values shouldn't be a problem { SetFormat, Float, % "0." . A_Index - 1 ; Begins with 0.0 and goes up by .1 every iteration testVar1 += 0 ; This tries adjusting the variable to our new setting rTestVar1 := Mod(testVar1, 2) If (rTestVar1 = rcheck) ; Do the values match? { var1 := testVar1 ; Update to optimal value Break ; Exit Loop } Else testVar1 := var1 ; Reset the testing variable to the original value } Return
If you want to see it in context, I used it in a custom delayed hibernate script that I made, which is here:
; press win+shift+control+alt+h to hibernate the computer (in set time) #+^!h:: If (HiberHasRun = True) ; Pressing the hotkey again while the script is running will tell you how much time is left to the nearest tenth of a second or let you cancel it { If (rmillisec!="") { WaitTime -= %rmillisec% rmillisec := } If (TimeSpentWaiting!="") WaitTime -= %TimeSpentWaiting% GoSub SeparateTimes SetTimer, TimeSpentWaiting, Off MsgBox,65,%WaitTime% milliseconds remain,% "Still waiting for " . hrs . " hours " . min . " minutes " . sec . " seconds and then hibernating the computer.`nPress Cancel or close this message box to stop, or press OK to continue." SetTimer, TimeSpentWaiting, On IfMsgBox Cancel { SetTimer, TimeSpentWaiting, Off HiberHasRun := False SetFormat, Float, 0.6 Exit } } Else ; This is the main script { hrs := min := sec := WaitTime := GoSub GetUserHibernateTime GoSub ConfirmWithOutput sleep %rmillisec% SetTimer, TimeSpentWaiting, 100 HiberHasRun := True sleep % WaitTime - rmillisec If WinExist("MediaMonkey") || WinExist("Winamp") || WinExist("Windows Media Player") ; setup media players here if you want { Send Media_Stop ; WinClose } WaitTime := TimeSpentWaiting := HiberHasRun := False SetTimer, TimeSpentWaiting, Off SetFormat, Float, 0.6 DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0) } return ConfirmWithOutput: If (LastLine = 3) { If (TimeArray1="") || (TimeArray2="") || (TimeArray3="") { MsgBox,48,,Please try again and make sure there are no empty values.`n`ne.g. "5::30" is not an acceptable value.`nUse "5:0:30" instead. GoSub GetUserHibernateTime } If (WaitTime="") { WaitTime := (TimeArray1 * 60 * 60 * 1000) + (TimeArray2 * 60 * 1000) + (TimeArray3 * 1000) } Gosub SeparateTimes MsgBox,65,Wait for %WaitTime% milliseconds,% "Waiting for " . hrs . " hours " . min . " minutes " . sec . " seconds and then hibernating the computer." IfMsgBox, Cancel Exit } Else If (LastLine = 2) { If (TimeArray1="") || (TimeArray2="") { MsgBox,48,,Please try again and make sure there are no empty values.`n`ne.g. "5:" is not an acceptable value.`nUse "5:0" instead. GoSub GetUserHibernateTime } If (WaitTime="") { WaitTime := (TimeArray1 * 60 * 1000) + (TimeArray2 * 1000) } GoSub SeparateTimes MsgBox,65,Wait for %WaitTime% milliseconds,% "Waiting for " . hrs . " hours " . min . " minutes " . sec . " seconds and then hibernating the computer." IfMsgBox, Cancel Exit } Else If (LastLine = 1) { If (TimeArray1="") || (TimeArray1="0") { MsgBox,65,Hibernate Now,Will hibernate the computer immediately. IfMsgBox, Cancel Exit } If (WaitTime="") { WaitTime := (TimeArray1 * 1000) } GoSub SeparateTimes MsgBox,65,Wait for %WaitTime% milliseconds,% "Waiting for " . hrs . " hours " . min . " minutes " . sec . " seconds and then hibernating the computer." IfMsgBox, Cancel Exit } Else { MsgBox,65,Hibernate Now,Will hibernate the computer immediately. IfMsgBox, Cancel Exit } Return GetUserHibernateTime: TimeArray1 := TimeArray2 := TimeArray3 := SetFormat, Float, 0.13 InputBox, TimeInput,Hibernate in Hrs:Min:Sec,Enter the time to wait in values separated by colons (:)`nAll integer and decimal values are acceptable (leave blank for no wait).`n`ne.g.`n"56.75" will wait for 56.75 seconds`n"3:0" or "2.5:30" will wait for 3 minutes`n"3:130:85" will wait for 5 hours 11 minutes 25 seconds,,450,250 If ErrorLevel Exit StringSplit, TimeArray, TimeInput, :, %A_Space% Loop, parse, TimeInput, :, %A_Space% LastLine := A_Index Return SeparateTimes: hrs := floor(WaitTime/1000/60/60) min := floor(WaitTime/1000/60) - floor(WaitTime/1000/60/60)*60 sec := WaitTime/1000 - (floor(WaitTime/1000/60/60)*60*60 + (floor(WaitTime/1000/60) - floor(WaitTime/1000/60/60)*60)*60) testSec := sec rCheck := Mod(sec, 2) rwCheck := Mod(WaitTime, 2) WaitSub := WaitTime rmillisec := (sec - floor(sec))*1000 Loop 13 { SetFormat, Float, % "0." . A_Index - 1 testSec += 0 rTestSec := Mod(sec, 2) If (rTestSec = rCheck) { sec := testSec Break } Else testSec := sec } Loop 13 { SetFormat, Float, % "0." . A_Index - 1 WaitSub += 0 If (Mod(WaitSub, 2) = rwCheck) { WaitTime += 0 break } Else WaitSub := WaitTime } Return TimeSpentWaiting: TimeSpentWaiting += 100 Return
There's probably some other places where it could be more optimized, but my knowledge is just mediocre. I can confirm that this works quite well, however.