Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Easy way to set SetFormat to optimal decimal value


  • Please log in to reply
No replies to this topic
Inserio
  • Members
  • 2 posts
  • Last active: Oct 28 2015 04:05 PM
  • Joined: 07 Jul 2015

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.