2014-12-12

3/2 returns 1 or 1.5?

3/2は1と1.5のどちらを返すか?

The answer is 1, in FME 2014 and earlier.
答は1です。FME 2014以前では。

In almost all the programming languages e.g. C, Python 2.x, Tcl, the / operator returns an integer value if both operands are integers. As well, 3/2 entered with the Arithmetic Editor of FME Workbench has returned 1 for a long time. I think the manner of math operations of FME has been basically inherited from C.
3/2 returns 1, 3.0/2, 3/2.0, or 3.0/2.0 returns 1.5.
C, Python 2.x, Tclなどのほとんど全てのプログラミング言語では、/演算子は、両オペランドが整数のときは整数値を返します。同様に、FMEワークベンチの数式エディタで入力された3/2は、長い間1を返してきました。FMEにおける算術演算の仕方は、基本的にはCから継承されているのだと思います。
3/2は1を返し、3.0/2, 3/2.0 または 3.0/2.0は1.5を返します。
=====
2014-12-17:
Added "2.x" to Python since 3/2 returns 1.5 in Python 3.
See also the comments in this article.
Python 3では、3/2は1.5を返すので、Pythonに「2.x」を追記しました。
この記事についてのコメントも参照してください。
=====

In some cases, the rule "int/int returns int" can be used effectively.
For example, 0-based sequential index of a grid cell can be converted to row, column index with these expressions.
row index = sequential index / number of columns
column index = sequential index % number of columns
あるケースでは、この「整数/整数は整数を返す」というルールは効果的に使えます。
例えば、次の式により、グリッドセルに与えられた0から始まる連番を行, 列のインデクスに変換することができます。
行インデクス = 連番 / 列数
列インデクス = 連番 % 列数













On the other hand, however, it's also a fact that the rule has brought a confusion to many users who expect 3/2 returns 1.5. If you don't know the rule, you will have to consume long time to find the issue in the workspace. I've called it "integer division trap".
しかし一方では、このルールが、3/2が1.5を返すことを期待する多くのユーザーに混乱をもたらしてきたのも事実です。このルールを知らなければ、ワークスペースにおける問題点を見つけるのに長い時間を費やさなければなりません。私はこれを「整数除算のワナ」と呼んできました。

Now, I got an important information that says the rule will be changed. The / operator in FME 2015 will always perform floating point division, even if both operands are integers.
さて、このルールが変更されるという重要な情報を得ました。FME 2015における/演算子は、両オペランドが整数であっても、常に小数点数の除算を行うことになるのです。

Yes. The answer will be 1.5, in FME 2015.
そう。FME 2015では、答は1.5になります。

I was surprised when I heard it from Safe, and it was hard to accept such a radical change, honestly. Although I now understand it's reasonable for many users, I'm afraid of side-effects against existing workspaces.
Safe社からこれを聞いたときは驚き、正直なところ、そのような過激な変更は受け入れ難いものでした。今は多くのユーザーにとって妥当なことであると理解していますが、既存のワークスペースに対する副作用は心配です。

In my quick test, math expressions in existing workspaces created with FME 2014 were performed in the current rule "int/int returns int" when I ran it with FME 2015 Workbench.
It's good.
But, if you once open the expression with the Arithmetic Editor of FME 2015 and closed the transformer parameters dialog with OK button, the rule will be changed to the new one "/ operator always performs floating point division".
We need to be aware it.
簡単なテストをしたところ、FME 2014で作成した既存のワークスペースにおける数式は、FME 2015のワークベンチで実行した場合でも現在のルール「整数/整数は整数を返す」で行われました。
これは良い。
ただ、FME 2015の数式エディタでその式を開き、トランスフォーマーのパラメータ設定ダイアログボックスをOKボタンで閉じると、新しいルール「/演算子は常に小数点数の除算を行う」に変更されます。
これには注意が必要です。

=====
2014-12-18:
As Mark@Safe commented, when you open a math expression containing / operator that was entered with FME 2014 (or earlier) with the Arithmetic Editor in FME 2015, this large warning message will appear.
Safe社マークさんがコメントしたように、FME 2014以前で入力された / 演算子を含む数式を FME 2015 の数式エディタで開いたときは、次のような大きな警告メッセージが表示されます。













However, it seems to appear only when opening the expression with the Arithmetic Editor.
If you modified the expression without using the Arithmetic Editor, or edited other parameter values, and then you close the transformer parameters dialog with [OK] button, the division behavior change will be applied to the transformer without the message.
I hope that such an implicit change will not happen.
Tested with FME 2015 beta build 15230.
しかし、これはその式を数式エディタで開くときだけ表示されるようです。
数式エディタを使わずにその式を修正したり、他のパラメータを編集したりしてからトランスフォーマーのパラメーター設定ダイアログボックスを [OK] ボタンで閉じると、そのトランスフォーマーについて、メッセージなしで除算の動作の変更が適用されます。
そのような暗黙の変更は起こらないことを望みます。
FME 2015 ベータ版 build 15230 でテストしました。
=====

In addition, I believe that the rule in Python and Tcl scripts will not change. Absolutely?
なお、Python、Tclスクリプトにおけるこのルールは変わらないはずです。もちろんですよね?
=====
2014-12-15
...was not "absolutely". The / operator in Python 3 has changed its behavior (3/2 returns 1.5). See also David's comment.
... 「絶対に」ということはありませんでした。Python 3 の / 演算子の動作には変更があります(3/2は1.5を返す)。ディビッドさんのコメントも参照してください。

Note: FME 2015 uses Python 2.7, at least in beta build 15225.
注: FME 2015はPython 2.7を使用しています、少なくともベータ版ビルド15225では。
=====

FME 2014 SP4 build 14433, FME 2015 Beta build 15225

9 comments:

  1. Hi Takashi,

    good read. For what it's worth, this change of behavior in FME 2015 mimics the changes in Python 3, where 3 / 2 == 1.5 and 3 // 2 == 1.

    Details here: https://www.python.org/dev/peps/pep-0238/

    But I agree, confusion is bound to follow when migrating existing workspaces to FME 2015. But again, the Zen of Python prevails (https://www.python.org/dev/peps/pep-0020/): explicit is better than implicit, so careful use of typecasts will prevent such problems.

    David

    ReplyDelete
    Replies
    1. Hi David, I didn't know the behavior of the / operator has been changed in Python 3.
      Thanks for the information.
      I strongly agree that explicit is better than implicit.

      One more information.
      I heard from Safe that math expressions in FME 2015 will be performed with native C++, will not be passed to Tcl interpreter any longer.
      Performance should be better than traditional Tcl interpreting.
      It's a good news :)

      Delete
  2. Thanks for sharing the bit about math expressions in FME 2015, that is fantastic news :-)

    ReplyDelete
  3. Not sure if my comment went through, so here it is again...

    We were very careful to avoid just changing the behaviour for existing workspaces, as we knew that would be very bad. So old workspaces will run as they always did.

    You are correct that opening and closing the transformer will change the behaviour. However, when that happens a very large warning message appears:

    https://dl.dropboxusercontent.com/u/4200566/Blog-FloatChange.jpg

    Hope this helps

    Mark

    ReplyDelete
    Replies
    1. Hi Mark, thanks for the comment.

      I saw the large warning message when I opened a transformer parameter containing the / operator with the Arithmetic Editor.

      See this workspace example, which was created with FME 2014 SP5.
      https://www.dropbox.com/s/3tak0ux1q8t3cmu/141217DivisionOperator_2014.fmw?dl=0

      Test with FME 2015 b15225:
      Open the Offsetter Parameters dialog
      -> Open the Arithmetic Editor for the "Y Offset" parameter
      -> The warning message appears; close it with [OK] button
      -> Close the Arithmetic Editor with [Cancel] button

      Then, if you close the Offsetter Parameters dialog with [Cancel] button, the change will not applied.
      But if you close the dialog with [OK] button, the change will be applied even though you've closed the Arithmetic Editor with [Cancel].
      I think it's ideal that the change will not be applied if the Arithmetic Editor has been closed with [Cancel] button.

      The warning message describes "what's going on", but doesn't describe "what you should do".
      If the change will be applied anyway when the transformer parameters dialog has been closed with [OK] button, I hope the message will be enhanced so that the user can understand "what you should do".
      For example, "It is recommended that you explicitly cast the return value from the division operator if you expect it returns an integer value. e.g. @int(3 / 2)."
      Not sure if it is grammatically correct as an English sentence...

      Delete
    2. I tried another pattern.
      If you modified the "Y Offset" parameter directly without using the Arithmetic Editor and closed the Offsetter Parameters dialog with [OK] button, the change will be applied without showing the warning message.
      hmm...

      Delete
    3. so, it may be better that the "Division Behavior Change" message will appear when the Transformer Parameters dialog is opened rather than the Arithmetic Editor, if a parameter setting of the transformer contains a division operator.

      Delete
    4. One more.
      The Offsetter has the / operator only in the "Y Offset" parameter.
      If you modify X or Z rather than Y, the message will not appear but the change will be applied when you have closed the parameters dialog with [OK].
      There are many cases where the change will be applied without the message.
      Tested with FME 2015 b15260.

      Delete
    5. correction for a typo.
      Tested with FME 2015 "b15230".

      Delete