1

This isn not really a problem. It might not be directly caused by powershell, but I have encountered this weird phenomenon today. I even got bored and made a small script that clicks in a loop, so nothing serious.

Here is what is weird: When I added a small sleep into the loop to not have my system die due to gorrilions of clicks a second, I noticed a HUGE difference in frequency between:

sleep 0.50001 - it was clearly visible that it was clicking twice a second.

and

sleep 0.5 - was a LOT faster - it felt like at least 10 clicks a second.

I have tested this on the browser "game" cookie clicker to visualize this (okay, and to get rid of some boredom) and it got really obvious there.

To the question: Can anyone explain to me why 0.5 is apparently a lot faster than 0.50001 in powershell?

PS: I have tested it with 0.4, 0.6 too - its as if 0.5 is the border between normal and subsonic speed.

tukan
  • 17,050
  • 1
  • 20
  • 48
Flying Thunder
  • 890
  • 2
  • 11
  • 37
  • 2
    Seconds take an `[int]` and .NET rounds to nearest even integer by default :-) Use the `-Milliseconds` parameter explicitly and specify 400, 500 or 600 instead – Mathias R. Jessen Feb 23 '18 at 11:14
  • Take a look at [this](https://stackoverflow.com/questions/48864295/powershell-int-variable-with-decimal-number/48864546#48864546) answer by mklement0. – Vivek Kumar Singh Feb 23 '18 at 11:24

2 Answers2

6

You're the victim of midpoint rounding!

Let's have a look at the syntax for Start-Sleep:

PS C:\> Get-Command Start-Sleep -Syntax

Start-Sleep [-Seconds] <int> [<CommonParameters>]

Start-Sleep -Milliseconds <int> [<CommonParameters>]

As you can see, the default parameter set takes the Seconds to sleep as an integer.

When you supply a Double, PowerShell tries to convert your input value to an integer, and 0.5 and below gets rounded to 0, thanks to the default midpoint rounding mode employed by .NET

So [int]0.50001 is equal to 1 and [int]0.5 is equal to 0

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
0

The issue is rounding as Jessen said.

There is one thing:

Sleep is not a PowerShell function it is a batch file's one (as Jessen correctly said it is also a PowerShell an alias to Start-Sleep do not confuse them.). Not to confuse them Microsoft probably decided to use Start-Sleep for PowerShell instead of simple Sleep and added alias for that.

If you want to do it the PowerShell way use Start-Sleep. You won't get confused if you add the -Milliseconds there:

Start-Sleep [-Seconds] <int>  [<CommonParameters>]
Start-Sleep -Milliseconds <int>  [<CommonParameters>]

To check that it is "only" alias

PS U:\> get-alias -name sleep

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           sleep -> Start-Sleep
tukan
  • 17,050
  • 1
  • 20
  • 48
  • `sleep` is an alias for `Start-Sleep`. – Joey Feb 23 '18 at 11:26
  • @Joey Yes, that is true. You have to just watch out if you are in the mixed environment using batch and powershell not to mix them. That is why I prefer `Start-Sleep` over the alias `Sleep`. And that is why I have written that Sleep is a batch file function. – tukan Feb 23 '18 at 11:28
  • It's still wrong. `sleep` is not a native command present on normal Windows installations. Within PowerShell it's the alias and thus equivalent to `Start-Sleep`. – Joey Feb 23 '18 at 11:31
  • @Joey It is native command within batch file not a command. It will work everywhere. You can create a `test.bat` and put there `SLEEP 10` it will work there - normal Windows installation. – tukan Feb 23 '18 at 11:33
  • Normal Windows installation here: `'sleep' is not recognized as an internal or external command, operable program or batch file.` It has been part of some Windows Resource Kits in the past. Maybe you have one of them installed. Or GnuWin32 or similar. But the built-in way of waiting on Windows would be either `timeout` or `ping`, but not `sleep`. – Joey Feb 23 '18 at 12:59
  • @Joey that all depends on your definition of "normal" - if you mean by out-of-the box then no. e.g. I'm using windows 2003 with Windows resource Kit. Running it produces `sleep /? Usage: sleep time-to-sleep-in-seconds sleep [-m] time-to-sleep-in-milliseconds sleep [-c] commited-memory ratio (1%-100%)` – tukan Feb 23 '18 at 14:52