LoginSignup
0
0

More than 5 years have passed since last update.

X = 4.3 - 4.2 このとき、Xの値は?(Decimal in PowerShell編)

Last updated at Posted at 2015-06-08

はじめに

X = 4.3 - 4.2 このとき、Xの値は?(後編)では、PowerShellとHaskellの連携による、小数どうしの計算方法を紹介した。

その後、iakioさんからのアドバイスで、Decimal型どうしの演算で誤差がなくせることが分かったので、関数化してみた。

せっかくなので、比較演算子の記号を分かりやすくしたり、%(パーセント)での計算も可能にしてみた。

定義

PowerShell
function Calculate-Expression([string]$Expression){
  [string]$Expression_Parsed = `
    (((((((( $Expression `
      -replace '([\+\-\*\/\(\)])',' $1 ') `
      -replace '%' ,' / 100 ') `
      -replace '<=',' -le ') `
      -replace '>=',' -ge ') `
      -replace '!=',' -ne ') `
      -replace '=' ,' -eq ') `
      -replace '<' ,' -lt ') `
      -replace '>' ,' -gt ').Split(" ") | `
    ForEach{
      $r = 0
      if([Decimal]::TryParse($_,[ref]$r)){
        [string]$r + 'd'
      }else{
        [string]$_
      }
    }
  Invoke-Expression $Expression_Parsed
}

Set-Alias calc Calculate-Expression

使用例

PowerShell
calc "4.3 - 4.2" #誤差なく計算できる
#0.1

calc "4.3 - 4.2 = 0.1" #比較演算子を分かりやすく
#True

calc "50 * 80%" #パーセントでの計算もできる
#40

解説

1.PowerShell形式に変換+各項に分解

PowerShell
    (((((((( $Expression `
      -replace '([\+\-\*\/\(\)])',' $1 ') `
      -replace '%' ,' / 100 ') `
      -replace '<=',' -le ') `
      -replace '>=',' -ge ') `
      -replace '!=',' -ne ') `
      -replace '=' ,' -eq ') `
      -replace '<' ,' -lt ') `
      -replace '>' ,' -gt ').Split(" ")

・文字列で渡ってきた計算式を、PowerShellで演算できる形式に変換(=⇒-eq、!=⇒-neなど)
・%は1/100を表す(例:90%=0.9)
・演算子の前後に半角スペースを付加
・計算式を各項に分解(Split関数)
例えば、式「1+2=3」は、以下のように分解される

1
+
2
-eq
3

2.数値をDecimal変換

PowerShell
    ForEach{
      $r = 0
      if([Decimal]::TryParse($_,[ref]$r)){
        [string]$r + 'd'
      }else{
        [string]$_
      }
    }

・項ごとにTryParse関数を使い、Decimal型への変換を行う
・Decimal型へ変換できる場合は、後ろにdを付ける(後でDecimal型として計算するため)
・上記以外はそのまま文字列を返す
例えば、式「1+2=3」は、以下のように変換される

1d
+
2d
-eq
3d

上記配列をstring型変数「$Expression_Parsed」に格納する

PowerShell
$Expression_Parsed
#1d + 2d -eq 3d

$Expression_Parsedを実行(計算)する

PowerShell
  Invoke-Expression $Expression_Parsed

エイリアス(別名)を定義

PowerShell
Set-Alias calc Calculate-Expression

Calculate-Expression関数のエイリアスとしてcalcを指定。
※エイリアスの詳細についてはこちらを参照

おわりに

今回紹介した関数を応用すれば、例えば、ユーザがテキストボックスで入力した式を誤差なく計算したい場合に活用できるかもしれない。

そもそも、小数どうしの四則演算くらい、特に工夫しなくても正確に計算して欲しいところだが。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0