Est-il possible d'utiliser un logarithmique naturel dans votre code SmartPy?
4 réponses
- votes
-
- 2020-07-09
Commeexpliquépar arvidj,iln'y apas de chiffres depointsflottants dans Michelson (ou SmartPyPy),aucun
exp
oulog
fonction.Touten travaillant avec desnombresnaturels,vouspouvezmettreen œuvre à lamain quelquesexemples quipeuvent vous suffire ounon. Quelquesexemplesici: https://smartpy.io/dev/index.html?template=Calculator.py , https://smartpy.io/dev/index. HTML? Modèle=WorldCalculator.py
Unexemple completpour vous:
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)
éditer. Ajout d'uneimplémentation deprécisionfixe dans SmartPy.
https://smartpy.io/dev/index.html?template=fixe_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
Vous devez lefairemanuellement ... voici une approchepour calcul
log(x)
en supposant que vous représentezx
en tant quefraction- trouveentier M àtravers une recherchebinairetelle que 2 ^m & lt;=x & lt;2 ^ (m + 1) (Mpeut êtrenégatif)
- letm '=m + (1 si| x/2 ^ (m + 1) -1 -1| & lt;| x/2 ^m-1| 0) (lesplusproches dem oum + 1)
- let x '=x/2 ^m',notez que| X'-1|& lt;1/3et journal (x)=journal (2 ^m 'x')=m 'journal (2) +journal (x')
- Soit Y=(1-x ')/(1 + x'),note que -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
-
Cen'estpas évidentpourmoi que la questionportait sur desnuméros depointsflottants représentésici comme desfractions ou simplement desentiers.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
J'ai un contrat dejournalbinaire qui utilisepeu demultiplicationset peut être ajustépourtouteprécision depointfixe: https://github.com/sophia-gold/michelson/blob/master/log2fix.tz .Jene pensepas que celapuisse être écrit dans SmartPy,carje l'ai vérifié,ilmanque des changements.Enfonction de vosbesoins,vouspouvez utiliser cela avec le changement deméthode debase ou d'Arthur.
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.
-
Les changements sontmanipuléspar SmartPy comme dans Python (depuisfévrier dernier).`<<`et `>>`.Devrait être correctement documenté (maisne sontpas comme d'aujourd'hui,ce quiest une honte).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
-
Avez-vous la version Ligo de ce script Michelson? Serait utile demieux comprendreDo you have the ligo version of this michelson script?Would be helpful to understand it better
- 0
- 2020-07-09
- George Mathew Kanianthara
-
@Georgemathewkaniantharan'apas de version de Ligo,mais l'article relié dans le commentaireexplique comment celafonctionne.@GeorgeMathewKanianthara don't have a ligo version, but the article linked in the comment explains how it works.
- 0
- 2020-07-09
- Sophia Gold
-
Une version SmartPy avec la version detest (nous avons dû réparer l'interprètepour les quarts detravail).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
Iln'y apas d'instruction de cetype dans Michelson,doncprobablement lamême chosepour SmartPy. Deplus,Michelsonn'apas de valeurs depointsflottants. Vouspouvezimplémenter une version dejournalnaturel vous-même utilisant des divisions répétées,toutefois,laprécision subira. Notez également que celapeut être coûteux augaz.
Une optionest d'avoir le contrat deprendre le contrat deprendre leparamètre de la chaîne horstension de l'exposant calculé,puis de vérifier le contrat de vérifier que l'exposantesten effet correct. Au lieu de (enpseudocode):
def contract(some_parameter): exponent = nl(some_parameter)
avoir
def contract(expected_exponent, some_parameter): assert e^expected_exponent = some_parameter
Maisencore unefois,vous voustransformerez dans la question que l'exponciationn'estpas disponible dans Michelson (mais que vouspourriezmettreen œuvre avec desmultiplications répétées)et non des valeurs depointsflottants.
Nouspouvonspeut-être vous aidermieux si vous donnezplus de contexte à la question que vous souhaitez résoudre?
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?
Sinon,existe-t-il une solution alternative demettreen œuvre une composantejournalnaturelle dans votre code de contratintelligent?