2017-09-18 2 views
2

Julia a une fonction intégrée pour arrondir à n chiffres significatifs. signif(0.0229, 2) arrondira à deux chiffres significatifs et donnera 0.023.Hacher ou tronquer à n chiffres significatifs

Comment est-ce que je peux couper ou tronquer à n chiffres significatifs de sorte que j'obtiendrais 0.022 à la place?

+0

Will 'myfloor (x, d) = round (x -0.5 * 10.0^(- d), d) 'être assez bon? –

+0

'myfloor (0.0229, 2)' donne '0.02', il devrait donner' 0.022' – clay

+0

Ah ... Je vois, j'ai mal compris la question. Mais ayez une suggestion longue mais fonctionnante dans une réponse ci-dessous. –

Répondre

3

Eh bien, pas très imaginatif. Utilisé @edit signif(0.229,2) pour trouver la source et remplacer round par floor (et ajouté un Base. pour le référencement correct du module). Voici le résultat:

function mysignif(x::Real, digits::Integer, base::Integer=10) 
    digits < 1 && throw(DomainError(digits, "`digits` cannot be less than 1.")) 

    x = float(x) 
    (x == 0 || !isfinite(x)) && return x 
    og, e = Base._signif_og(x, digits, base) 
    if e >= 0 # for numeric stability 
     r = trunc(x/og)*og 
    else 
     r = trunc(x*og)/og 
    end 
    !isfinite(r) ? x : r 
end 

Donner:

julia> mysignif(0.0229,2) 
0.022 
+0

Impressionnant. Il ne gère pas correctement les nombres négatifs. Je suis sûr que vous pouvez facilement résoudre ce problème. – clay

+0

@clay Oui, il est facile à corriger (en fait, le comportement souhaité sur les négatifs dépend de l'application). Pour corriger, remplacer 'floor' par' trunc' [Je le ferai aussi dans la réponse] –

1

J'ai trouvé une version à Maple et porté à Julia:

function signifChop(num, digits) 
    if num == 0.0 then 
     return num 
    else 
     e = ceil(log10(abs(num))) 
     scale = 10^(digits - e) 
     return trunc(num * scale)/scale 
    end 
end 

# Test cases for signifChop 
println("$(signifChop(124.031, 5))") 
println("$(signifChop(124.036, 5))") 
println("$(signifChop(-124.031, 5))") 
println("$(signifChop(-124.036, 5))") 
println("$(signifChop(0.00653, 2))") 
println("$(signifChop(0.00656, 2))") 
println("$(signifChop(-0.00653, 2))") 
println("$(signifChop(-0.00656, 2))")