スマートコードで自然対数を使用することは可能ですか?
4 回答
- 投票
-
- 2020-07-09
Arvidjが説明しているように、Michelson(またはSmartPy)には浮動小数点数はなく、
exp
またはlog
関数もありません.自然数を操作しながら、手作業でいくつかの例を実装できますが、これでは十分な場合と不十分な場合があります.ここにいくつかの例: https://smartpy.io/dev/index.html?template=calculatorpy 、 https://smartpy.io/dev/index html?template=worldCalculator.py
あなたのための完全な例:
import smartpy as sp class Calculator(sp.Contract): def __init__(self): self.init(value = 0) @sp.entry_point def test(self, x): self.data.value = self.log2(x) @sp.global_lambda def log2(x): result = sp.local('result', 0) y = sp.local('y', x) sp.while 1 < y.value: result.value += 1 y.value //= 2 sp.result(result.value) if "templates" not in __name__: @sp.add_test(name = "Calculator") def test(): c1 = Calculator() scenario = sp.test_scenario() scenario += c1 scenario += c1.test(1000) scenario.verify(c1.data.value == 9)
編集. SmartPyに固定精度の実装を追加します.
https://smartpy.io/dev/index.html?template=fixed_precision.py
As explained by Arvidj, there are no floating point numbers in Michelson (or SmartPy), no
exp
orlog
function.While working with natural numbers, you can implement by hand some examples which may or may not be enough for you. Some examples here: https://smartpy.io/dev/index.html?template=calculator.py, https://smartpy.io/dev/index.html?template=worldCalculator.py
A complete example for you:
import smartpy as sp class Calculator(sp.Contract): def __init__(self): self.init(value = 0) @sp.entry_point def test(self, x): self.data.value = self.log2(x) @sp.global_lambda def log2(x): result = sp.local('result', 0) y = sp.local('y', x) sp.while 1 < y.value: result.value += 1 y.value //= 2 sp.result(result.value) if "templates" not in __name__: @sp.add_test(name = "Calculator") def test(): c1 = Calculator() scenario = sp.test_scenario() scenario += c1 scenario += c1.test(1000) scenario.verify(c1.data.value == 9)
EDIT. Adding a fixed precision implementation in SmartPy.
https://smartpy.io/dev/index.html?template=fixed_precision.py
-
- 2020-07-09
手動で行う必要があります...
log(x)
を分数として表すと仮定してx
を計算するための1つのアプローチを次に示します.- 2 ^m&lt;=x&lt;となるように、二分探索で整数mを見つけます.2 ^(m + 1)(mは負の場合があります)
- letm '=m +(1if | x/2 ^(m + 1)-1|&lt;| x/2 ^m-1| else 0)(mまたはm + 1の最も近いもの)
- x '=x/2 ^m'とし、| x'-1|に注意してください.&lt;1/3およびlog(x)=log(2 ^m'x ')=m'log(2)+ log(x')
- y=(1-x ')/(1 + x')とし、-1/7&lt;y&lt;1/5
- log(x ')〜=-2 y-2 y ^ 3/3
You have to do it manually... Here's one approach for compute
log(x)
assuming you are representingx
as a fraction- find integer m through binary search such that 2^m <= x < 2^(m+1) (m may be negative)
- let m' = m + (1 if |x/2^(m+1)-1| < |x/2^m-1| else 0) (the closests of m or m+1)
- let x' = x / 2^m', note that |x'-1| < 1/3 and log(x) = log(2^m' x') = m' log(2) + log(x')
- let y = (1-x')/(1+x'), note that -1/7 < y < 1/5
- log(x') ~= - 2 y - 2 y^3 / 3
-
ここで分数または単に整数として表される浮動小数点数についての質問であったことは私には明らかではありません.It's not obvious to me that the question was about floating point numbers represented here as fractions or simply integers.
- 0
- 2020-07-09
- FFF
-
- 2020-07-09
乗算をほとんど使用せず、任意の固定ポイント精度に調整できるバイナリログの契約があります: https://github.com/Sophia-Gold/michelson/blob/master/log2fix.tz .前回チェックしたところシフトがないのでSmartPyで書けるとは思いません.必要に応じて、ベースの変更またはアーサーの方法でこれを使用できます.
I have a contract for binary log that uses few multiplications and can be adjusted for any fixed point precision: https://github.com/Sophia-Gold/michelson/blob/master/log2fix.tz. I don't think it can be written in SmartPy because last I checked it lacks shifts. Depending on your needs you could use this with change of base or Arthur's method.
-
シフトはPythonと同様にSmartPyによって処理されます(昨年2月以降).`<<`と `>>`.適切に文書化する必要があります(ただし、今日の時点ではありません.これは残念です).Shifts are handled by SmartPy as in Python (since last February). `<<` and `>>`. Should be properly documented (but are not as of today, which is a shame).
- 2
- 2020-07-09
- FFF
-
このmichelsonスクリプトのligoバージョンはありますか?それをよりよく理解するのに役立ちますか?Do you have the ligo version of this michelson script?Would be helpful to understand it better
- 0
- 2020-07-09
- George Mathew Kanianthara
-
@GeorgeMathewKaniantharaにはligoバージョンはありませんが、コメントにリンクされている記事でその仕組みが説明されています.@GeorgeMathewKanianthara don't have a ligo version, but the article linked in the comment explains how it works.
- 0
- 2020-07-09
- Sophia Gold
-
SmartPyバージョンとテストバージョン(シフトのインタープリターを修正する必要がありました).https://smartpy.io/dev/index.html?template=fixed_precision.pyA SmartPy version with the test version (we had to fix the interpreter for shifts). https://smartpy.io/dev/index.html?template=fixed_precision.py
- 2
- 2020-07-10
- FFF
-
- 2020-07-09
Michelsonにはそのような指示がないため、SmartPyについても同じことが言えるでしょう.さらに、Michelsonには浮動小数点値がありません.繰り返し除算を使用して、自然対数のいくつかのバージョンを自分で実装することもできますが、精度が低下します.また、これはガスでコストがかかる可能性があることに注意してください.
1つのオプションは、契約に、指数がオフチェーンで計算されたパラメーターを取り込んでもらい、次に、指数が実際に正しいことを契約に検証させることです. (擬似コードで)の代わりに:
def contract(some_parameter): exponent = nl(some_parameter)
持っている
def contract(expected_exponent, some_parameter): assert e^expected_exponent = some_parameter
しかし、繰り返しになりますが、Michelsonではべき乗が利用できず(ただし、乗算を繰り返すことで実装できます)、浮動小数点値も利用できないという問題になります.
解決したい問題についてより多くのコンテキストを提供すれば、私たちはおそらくあなたをより良く助けることができますか?
There is no such instruction in Michelson, so probably the same goes for SmartPy. Furthermore, Michelson does not having floating point values. You could implement some version of natural log yourself using repeated divisions, however, precision will suffer. Also, note that this can be costly in gas.
One option is to have the contract take the contract take in parameter the exponent calculated off-chain, and then have the contract verify that the exponent is indeed correct. Instead of (in pseudocode):
def contract(some_parameter): exponent = nl(some_parameter)
have
def contract(expected_exponent, some_parameter): assert e^expected_exponent = some_parameter
but again, you will turn into the issue that exponentiation is not available in Michelson (but which you could implement with repeated multiplications), and nor are floating points values.
We can perhaps help you better if you give more context to the issue you want to resolve?
そうでない場合、スマートコントラクトコードに自然対数コンポーネントを実装する別の方法はありますか?