Comment diviser int64 dans Nim?
Comment puis-je diviser int64?
let v: int64 = 100
echo v / 10
Erreur Error: type mismatch: got <int64, int literal(10)>
Exemple complet
import math
proc sec_to_min*(sec: int64): int =
let min = sec / 60 # <= error
min.round.to_int
echo 100.sec_to_min
PS
Et, est - il un moyen de jeter en toute sécurité int64à int, de sorte que le résultat serait intet non int64, avec le chèque de trop - plein.
Réponses
Il y a déjà eu un peu de discussion sur la int64division dans cette question et probablement une certaine amélioration de l'état actuel peut être apportée. Du problème ci-dessus:
- une bonne raison pour ne pas avoir de division flottante dans stdlib
int64est que cela pourrait entraîner une perte de précision et que l'utilisateur devrait donc explicitement convertirint64enfloat - encore, la
floatdivision entre lesinttypes est présente dans stdlib - sur un système 64 bits
intestint64(et vous avez donc une division entre int64 dans les systèmes 64 bits)
Pour votre cas d'utilisation, je pense que ce qui suit ( terrain de jeu ) devrait fonctionner (mieux vaut utiliser div au lieu de faire une division flottante puis d'arrondir):
import math
proc sec_to_min*(sec: int64): int = sec.int div 60
echo 100.sec_to_min
let a = high(int64)
echo a.int # on playground this does not raise error since int is int64
echo a.int32 # this instead correctly raises error
production:
1
9223372036854775807
/usercode/in.nim(9) in
/playground/nim/lib/system/fatal.nim(49) sysFatal
Error: unhandled exception: value out of range: 9223372036854775807 notin -2147483648 .. 2147483647 [RangeError]
PS: comme vous le voyez ci-dessus, la conversion standard a des contrôles de plage
Apparemment, la division entre les types int64 est terriblement dangereuse car elle invoque une horde éternelle de perte de vélos, mais au moins vous pouvez créer votre propre opérateur:
proc `/`(x, y: int64): int64 = x div y
let v: int64 = 100
echo v / 10
Ou
proc `/`(x, y: int64): int64 = x div y
import math
proc sec_to_min*(sec: int64): int =
int(sec / 60)
echo 100.sec_to_min
En ce qui concerne la conversion en int64to int, je ne suis pas sûr que cela ait beaucoup de sens, car la plupart des plates-formes fonctionneront intcomme un alias de int64. Mais bien sûr, vous pourriez compiler / exécuter sur une plate-forme 32 bits, où la perte serait tragique, vous pouvez donc toujours faire des vérifications à l'exécution:
let a = int64.high
echo "Unsurprising but potentially wrong ", int(a)
proc safe_int(big_int: int64): int =
if big_int > int32.high:
raise new_exception(Overflow_error, "Value is too high for 32 bit platforms")
int(big_int)
echo "Reachable code ", safe_int(int32.high)
echo "Unreachable code ", safe_int(a)
De plus, si vous rencontrez des conversions confuses en minutes, heures, jours, vous voudrez peut-être examiner différents types pour éviter d'ajouter des mois à des secondes (ou le faire de manière plus sûre).