PowerShell's (invariably case-insensitive) numeric-multiplier suffixes - kb, mb, gb, tb, pb - are binary (base 2) multipliers, i.e. kb corresponds to kibibytes (1024), mb to mebibytes (1024 ^ 2), ... rather than decimal (base 10) multipliers (kilobytes (1000), megabytes (1000 ^ 2), ...) - see Wikipedia for a complete list.
- This may be surprising, given that abbreviations such as MB nowadays more typically suggest a decimal multiplier (1000 ^ 2) and unambiguous binary abbreviations such as MiB now exist.[1]
(And, as you've discovered, File Explorer too uses the binary meaning of KB, MB, ...)
Thus, for instance, 19099648 / 1mb == 19099648 / [Math]::Pow(1024, 2) == 19099648 / 1048576, which evaluates to 18.21484375.
Casting the latter to [int] (which applies half-to-even midpoint rounding[2]) therefore yields 18 (because any fractional part less than .5 is always truncated).
Since you're formatting the number for display yourself, you could use MiB instead of MB to avoid the ambiguity:
"$([int] ($_.Length / 1mb)) MiB"
Alternatively, if you wanted to emulate decimal multipliers, you can take advantage of the fact that PowerShell's number literals also support scientific (exponent-based) notation, so that 1 million (1,000,000) can succinctly be expressed as 1e6 to express the decimal meaning of mega (M):[3]
"$([int] ($_.Length / 1e6)) MB"
As for VBA / VBScript:
Since no multiplier suffixes exist there, you must either spell out the implied numbers (e.g.
CInt(19099648 / 1048576)) or perform the equivalent exponentiation (e.g.
CInt(19099648 / (1024 ^ 2)))
[1] From the linked Wikipedia page (emphasis added): "Systems based on powers of 2, however, might use binary prefixes (kibi, mebi, gibi, ...) and their corresponding symbols (Ki, Mi, Gi, ...) or they might use the prefixes K, M, and G, creating ambiguity when the prefixes M or G are used." The Ki, Mi, Gi , ... units were introduced later, specifically to avoid the ambiguity of K, M, G. Strictly speaking, the initial chars. are all uppercase in both systems, with the exception of lowercase "k", which unambiguously implies the decimal system, if used correctly. For more information, see the binary prefixes Wikipedia article.
However, note that PowerShell is inherently case-insensitive, so that KB is the same as kb. Also, it is unlikely that unambiguously binary suffixes such as KiB will ever be implemented in PowerShell, given that the existing ones cannot neither be removed nor redefined for reasons of backward compatibility.
Finally, note that the inclusion of B, denoting bytes, in PowerShell's suffixes such as MB is somewhat unfortunate, given that they're simply numeric multipliers that can be applied to any number, whether or not it represents bytes. If PowerShell weren't constrained by backward compatibility, K, M, ... could be introduced as decimal multipliers, and Ki, Mi, ... as binary ones.
[2] See this answer for details.
[3] Note that number literals in this format result in [double] (System.Double) numbers, whereas applying the binary suffixes such as mb results in either [int] (System.Int32) or [long] (System.Int64), depending on the size of the resulting number. However, in the context of division (/) PowerShell implicitly outputs a [double] anyway for non-integer results. If needed, you can always cast to a suitable integer type.