aku1 发表于 2007-12-20 14:13:21 |
Arithmetic Precedence
Microsoft® Windows® 2000 Scripting Guide
Most of the calculations you carry out as a system administrator are likely to be simple ones, such as dividing bytes by 1,024 to convert the value to kilobytes. On occasion, however, you might need to carry out a calculation that involves more than one operator (for example, a calculation that adds two numbers and then divides that value). Because of that, it is important to understand arithmetic precedence.
VBScript does not treat the arithmetic operators (addition, subtraction, multiplication, and division) equally. Instead, when given an equation, VBScript always performs the math operations in this order:
1. |
Division |
2. |
Multiplication |
3. |
Addition |
4. |
Subtraction |
Why does that matter to you? Consider the following script, which adds two numbers, multiplies them by a third, subtracts a fourth, and then divides by a fifth: Wscript.Echo 1 + 2 * 3 - 4 / 5
When this script runs, the value 6.2 is echoed to the screen. Here is how that value is derived.
1. |
Because division takes precedence over all the other operations, the first thing VBScript does is divide 4 by 5, yielding .8. To VBScript, the equation now looks like this: 1 + 2 * 3 - .8
|
2. |
Next it multiplies 2 and 3, yielding 6. Now the equation looks like this: 1 + 6 - .8
|
3. |
Because addition is next in the order of precedence, it adds 1 and 6, yielding 7, and resulting in this equation: 7 - .8
|
4. |
Finally it subtracts .8 from 7, giving the final answer 6.2. |
Of course, this might not be the answer, or the equation, you expected. Instead, you might have preferred that VBScript:
1. |
Add 1 + 2. |
2. |
Multiply that value by 3. |
3. |
Subtract 4. |
4. |
Divide the total by 5. |
For this to happen, you need to use parentheses to indicate the preferred order of precedence. Parentheses always take precedence, regardless of the arithmetic operator being used. Because of this, your equation should be rewritten to ensure that the steps are carried out in the proper order. (When multiple parentheses are used, the equation within the innermost parentheses is evaluated first and the equation in the outermost parentheses evaluated last.) Wscript.Echo (((1 + 2) * 3) - 4) / 5 Formatting NumbersMicrosoft® Windows® 2000 Scripting Guide On its own, VBScript does not always format numbers in easy-to-read fashion. For example, one of the first scripts used in this chapter returned the free disk space on a hard drive. The value returned was 10842824704. This value is accurate but difficult to read; it would be much better to have the free space reported like this: 10,842,824,704. Likewise, a calculation performed earlier in this chapter returned the value 10340.4458007813. Rarely, if ever, will you require that type of precision when performing system administration tasks. Instead, it would be better to have the value returned as 10,340 or 10,340.45. These numbers not only are easier to read but also require less room to display. This is an important consideration when creating tabular output to be displayed on the screen. The FormatNumber function allows you to control how numbers are displayed in script output. FormatNumber requires you to specify the number to be formatted, followed by any or all of the parameters described in Table 2.16. For example, this line of code displays the number 37.874 with no decimal places (that is, the value 38 will be displayed): Wscript.Echo FormatNumber(37.874, 0)
Table 2.16 FormatNumber Parameters
Number of digits after the decimal point. | FormatNumber does not simply delete digits. Instead, it rounds the number to the closest value. For example, if you decide to display 11.6 with no decimal places, the value 12 will be displayed. By contrast, 19.2 is displayed as 19. If you use the value 1, the number of digits after the decimal point will be based on the regional and language options for the computer. | Use leading zero. | Values are: -1 True. Use the leading 0. 0 False. -2 Use the setting configured in the regional and language options for the computer. | Place negative numbers in parentheses. | Values are: -1 True. Put negative numbers in parentheses. 0 False. Do not put negative numbers in parentheses. -2 Use the setting configured in the regional and language options for the computer. | Group digits. | Values are: -1 True. Group digits using the group separator. 0 False. Do not group digits. -2 Use the setting configured in the regional and language options for the computer. |
To help make your scripts easier to read and maintain, you might want to use constants in place of the literal values. For example, in this script it is not readily apparent what the 0 means: Wscript.Echo FormatNumber(37.874, 0)
Using a constant makes the script easier to understand: Const NoDecimalPlaces = 0
Wscript.Echo FormatNumber(37.874, NoDecimalPlaces)
Because each of the FormatNumber parameters is optional you, can perform such tasks as grouping digits without specifying values for the other parameters. However, the parameter for grouping digits must still be the fifth item in the parameter list (after the number to be formatted and the other three optional parameters). To ensure that the parameters maintain the correct order, you can do one of the following: • | Use a "blank" parameter (that is, simply insert a comma without including a value). | • | Use the default value by setting each unused parameter to False. | • | Use the default value by setting each unused parameter to a constant that has been set to False. |
For example, in this script constants are assigned the appropriate values, and then used to format the result of 1 / 7: Const Decimals = 3
Const LeadingZero = True
Const UseParentheses = True
Const Default = False
NumberToFormat = 1 / -7
Wscript.Echo NumberToFormat
Wscript.Echo FormatNumber(NumberToFormat, Decimals)
Wscript.Echo FormatNumber(NumberToFormat, Default, LeadingZero)
Wscript.Echo FormatNumber(NumberToFormat, Default, Default, UseParentheses)
When the preceding script runs under CScript, the following output appears in the command window: -0.142857142857143
-0.143
-0.14
(0.14)
The following script snippet shows different ways to format the value returned when multiplying 33 by 454: Const GroupDigits = True
Const Default = False
Const NoDecimals = 0
NumberToFormat = 33 * 454
Wscript.Echo NumberToFormat
Wscript.Echo FormatNumber(NumberToFormat, Default, Default, Default, GroupDigits)
Wscript.Echo FormatNumber _
(NumberToFormat, NoDecimals , Default, Default, GroupDigits)
When the preceding script runs under CScript, the following output appears in the command window: 14982
14,982.00
14,982
Formatting PercentagesMicrosoft® Windows® 2000 Scripting Guide Sometimes raw numbers are not as meaningful as percentages. For example, event logs have a maximum size that can vary from computer to computer. Because of that, simply knowing the current size of an event log (a property that can be retrieved by using WMI) will not tell you whether the log is nearly full and should be backed up and cleared. In this case, it might be more useful to know the maximum allowed size (another property available through WMI) as well as the current size. This lets you determine what percentage of the event log is "full" and what percentage is still available. If you are going to retrieve numbers as percentages, it is a good idea to also report those numbers as percentages. For example, suppose you have an event log with a maximum size of 5,000,000 bytes and a current size of 3,127,354 bytes. To determine how full the event log is, you can divide 3,127,354 by 5,000,000. When you do the calculation, the value .6254708 is returned. To lessen the possibility of confusion, it is better to have this value returned as a percentage (63%). The FormatPercent function converts a number to a percentage; in effect, this means multiplying the number by 100 and then appending a percent symbol. However, FormatPercent also accepts the same optional parameters as FormatNumber. These parameters allow you to: • | Specify the number of digits to be displayed after the decimal point. | • | Place a leading 0 in front of fractional values (numbers less than 1 but greater than 0). | • | Display negative values in parentheses. | • | Group digits using a group separator (allowing you to display a value as 6,500,000% rather than 6500000%). |
The syntax for the FormatPercent function is identical to that for FormatNumber: You supply the value to be formatted, followed by zero or more parameters. As with FormatNumber, the order in which the parameters are presented is crucial. For example, the leading 0 must always be the second parameter following the value being formatted. If you do not want to specify a value for the first parameter (number of digits following the decimal point), use False as a placeholder for that parameter. The following script divides 1 by 7 and echoes the result. The script then uses FormatPercent to display the result as a percentage, with no decimal places. Const NoDecimals = 0
NumberToFormat = 1 / 7
Wscript.Echo NumberToFormat
Wscript.Echo FormatPercent(NumberToFormat, NoDecimals)
When the preceding script is run under CScript, the following output appears in the command window: 0.142857142857143
14%
|