package abstrasy.libraries.math;
import abstrasy.Bivalence;
import abstrasy.Buffer;
import abstrasy.Bytes;
import abstrasy.Node;
import abstrasy.PCoder;
import abstrasy.SELF;
import abstrasy.externals.AExtCachable;
import abstrasy.externals.AExtClonable;
import abstrasy.externals.AExtTools;
import abstrasy.externals.AExtVObject;
import abstrasy.interpreter.InterpreterException;
import abstrasy.interpreter.ORef;
import abstrasy.interpreter.StdErrors;
import abstrasy.libraries.io.External_Buffer;
import abstrasy.libraries.math.rjm.BigIntegerMath;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.concurrent.atomic.AtomicReference;
/**
* Abstrasy Interpreter
*
* Copyright : Copyright (c) 2006-2012, Luc Bruninx.
*
* Concédée sous licence EUPL, version 1.1 uniquement (la «Licence»).
*
* Vous ne pouvez utiliser la présente oeuvre que conformément à la Licence.
* Vous pouvez obtenir une copie de la Licence à l’adresse suivante:
*
* http://www.osor.eu/eupl
*
* Sauf obligation légale ou contractuelle écrite, le logiciel distribué sous
* la Licence est distribué "en l’état", SANS GARANTIES OU CONDITIONS QUELLES
* QU’ELLES SOIENT, expresses ou implicites.
*
* Consultez la Licence pour les autorisations et les restrictions
* linguistiques spécifiques relevant de la Licence.
*
*
* @author Luc Bruninx
* @version 1.0
*/
public class External_Integer extends AExtTools implements AExtClonable,
AExtCachable,
AExtVObject {
/* Nombre */
private AtomicReference<BigInteger> number = new AtomicReference<BigInteger>(BigInteger.ZERO);
//private BigInteger number = BigInteger.ZERO;
/**
* Constructeur par défaut
*/
public External_Integer() {
}
public External_Integer(BigInteger number) {
this.number.getAndSet(number);
}
/**
* Méthode implémentation du clonage
* @param bival
* @return
*/
@Override
public Object clone_my_self(Bivalence bival) {
External_Integer t = new External_Integer();
BigInteger n = BigInteger.ZERO;
t.number.getAndSet(n.add(number.get()));
return t;
}
/**
* Implémentation de la méthode init!:
* - ((new Math:Integer) 'init! x) où (:init! x) est équivalent à (:parse! x)
*
* @param startAt
* @return
* @throws Exception
*/
public Node external_mutator_init(Node startAt) throws Exception {
external_mutator_parse(startAt);
return SELF.get(); // retourner une référence de l'objet courrant...
}
/**
* Sérialisation du Integer...
* @param startAt
* @return
* @throws Exception
*/
public Node external_quote(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1, 2);
Node res = null;
res = abstrasy.externals.AExtTools.SerializationTK.createInitExpr(Node.createPattern(External_Integer.class.getName()), new Node(number.get().toString()));
return res;
}
/*
*
*/
private final static double LONG_MAX_VALUE = Long.MAX_VALUE;
private final static double LONG_MIN_VALUE = Long.MIN_VALUE;
private final BigInteger _convertArg_(Node arg) throws Exception {
long qt=arg.getQType();
if (qt==Node.TYPE_NUMBER) {
//number
double rint = arg.getNumber();
if (rint < LONG_MAX_VALUE && rint > LONG_MIN_VALUE)
return BigInteger.valueOf(Math.round(rint));
else
return new BigInteger("" + Math.rint(arg.getNumber()));
}
else if (qt==Node.TYPE_STRING) {
//string
String r = Node.node2VString(arg).getString();
if (r.startsWith("0x"))
return new BigInteger(r.substring(2), 16);
else if (r.startsWith("0o"))
return new BigInteger(r.substring(2), 8);
else if (r.startsWith("0b"))
return new BigInteger(r.substring(2), 2);
else if (r.startsWith("-0x"))
return new BigInteger(r.substring(3), 16).negate();
else if (r.startsWith("-0o"))
return new BigInteger(r.substring(3), 8).negate();
else if (r.startsWith("-0b"))
return new BigInteger(r.substring(3), 2).negate();
else
return new BigInteger(r);
}
else if (qt==Node.TYPE_BYTES) {
//bytes
return new BigInteger(arg.getBytes().getArray());
}
else if (arg.isDelegable()) {
if (arg.getQType() == Node.TYPE_EXTERNAL) {
Object o = arg.getExternal();
// tester d'abord les optimisations
if (o instanceof External_Integer)
// optimisation pour Integer
return ((External_Integer) o).number.get();
else if (o instanceof External_Decimal)
// optimisation pour Decimal
return ((External_Decimal) o).toInteger();
}
// pas d'optimisation...
// résolution générale...
// (:to-integer)
Node r = Node.VDelegable.evalMethod_or_null(arg, "to-integer", null);
if (r != null)
return _convertArg_(r);
// (:bytes)
r = Node.VDelegable.evalMethod_or_null(arg, PCoder.getMethod(PCoder.PC_BYTES), null);
if (r != null)
return _convertArg_(r);
// (:number)
r = Node.VDelegable.evalMethod_or_null(arg,PCoder.getMethod(PCoder.PC_NUMBER), null);
if (r != null)
return _convertArg_(r);
// (:string)
r = Node.VDelegable.evalMethod_or_null(arg, PCoder.getMethod(PCoder.PC_STRING), null);
if (r != null)
return _convertArg_(r);
}
// sinon, et bien...
throw new InterpreterException(StdErrors.extend(StdErrors.Invalid_parameter, "This object do not implement :to-integer method (" + arg.toString() + ")"));
}
private final BigInteger _getArg_(Node startAt, int i) throws Exception {
return _convertArg_(startAt.getSubNode(i, Node.TYPE_NUMBER | Node.TYPE_BYTES | Node.TYPE_STRING | Node.VTYPE_DELEGABLE));
}
/*
*
*/
private final BigInteger _getArg_lazy_(Node startAt, int i) throws Exception {
return _convertArg_(startAt.getSubNode_LazyValue(i, Node.TYPE_NUMBER | Node.TYPE_BYTES | Node.TYPE_STRING | Node.VTYPE_DELEGABLE));
}
/*
*
*/
/**
* Analyseur / convertiseur vers le type Integer.
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_parse(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
SELF.require_SELF_mutable();
number.getAndSet(_getArg_(startAt, 1));
return null;
}
public Node external_mutator_from_buffer(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
Buffer buffer = ((External_Buffer) AExtTools.getArgExternalInstance(startAt, 1, External_Buffer.class, Node.ACCESSVTYPE_MUTABLE_WRITELOCK)).getBuffer();
if (buffer.length() > 0)
number.getAndSet(new BigInteger(buffer.read_bytes()));
else
number.getAndSet(BigInteger.ZERO);
return null;
}
public Node external_to_buffer(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
Buffer buffer = new Buffer();
buffer.write_bytes(number.get().toByteArray());
External_Buffer res = new External_Buffer();
res.setBuffer(buffer);
return Node.createExternal(res);
}
public Node external_bytes(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
Bytes buffer = new Bytes(number.get().toByteArray());
return Node.createBytes(buffer);
}
/**
* Retourne le Decimal sous la forme d'un number.
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_number(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(number.get().doubleValue());
}
/**
* Retourne le Decimal sous la forme d'une chaîne de caractères dans la forme complète.
*
* @param startAt
* @return Node:string
* @throws Exception
*/
public Node external_string(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(number.get().toString());
}
/**
* Retourne l'Integer sous la forme d'une chaîne de caractères dans la Engineering (avec puissances de 10).
*
* @param startAt
* @return Node:string
* @throws Exception
*/
public Node external_string_E(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(new BigDecimal(number.get(), External_Context.context).toEngineeringString());
}
/**
* retourne le nombre exprimé sous la forme d'une chaîne hexadécimale
*
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_hex_string(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(number.get().toString(16));
}
/**
* retourne le nombre exprimé sous la forme d'une chaîne octale
*
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_oct_string(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(number.get().toString(8));
}
/**
* retourne le nombre exprimé sous la forme d'une chaîne octale
*
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_bin_string(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(number.get().toString(2));
}
/**
* méthode réservée pour faciliter la conversion des types...
*
* @return BigDecimal
*/
public BigDecimal toDecimal() {
String sn = number.get().toString();
MathContext mc = new MathContext(External_Context.context.getPrecision() + sn.length(), External_Context.context.getRoundingMode());
return new BigDecimal(sn, mc);
}
/**
* retourne un Node:Decimal qui correspond au nombre courant.
*
* @param startAt
* @return Node:Decimal
* @throws Exception
*/
public Node external_to_decimal(Node startAt) throws Exception {
String sn = number.get().toString();
MathContext mc = new MathContext(External_Context.context.getPrecision() + sn.length(), External_Context.context.getRoundingMode());
return Node.createExternal(new External_Decimal(new BigDecimal(sn, mc), mc));
}
/**
* Retourne un Node:number -1, si l'élément comparé est plus petit, 1 si l'élément comparé est plus grand, et 0 s'il s'ont de valeur
* égale.
*
* Est utilisé par =?, >?, <?, <=?, =>? et <>?....
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_compare(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
return new Node(number.get().compareTo(_getArg_(startAt, 1)));
}
public Node external_is_equ(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
return new Node(number.get().equals(_getArg_(startAt, 1)) ? Node.TRUE:Node.FALSE);
}
/**
* retourne la valeur absolue du nombre.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_abs(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return Node.createExternal(new External_Integer(number.get().abs()));
}
/**
* retourne un Node:nombre -1, 0 ou 1 selon que la valeur soit négative, nulle ou positive.
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_sgn(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(number.get().signum());
}
/**
* retourne TRUE si la valeur du nombre est zéro.
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_is_zero(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(number.get().signum() == 0 ? Node.TRUE: Node.FALSE);
}
/**
* retourne TRUE si le nombre est négatif.
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_is_negative(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(number.get().signum() < 0 ? Node.TRUE: Node.FALSE);
}
/**
* retourne TRUE si le nombre est positif.
*
* @param startAt
* @return
* @throws Exception
*/
public Node external_is_positive(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(number.get().signum() > 0 ? Node.TRUE: Node.FALSE);
}
/**
* retourne TRUE si le nombre est impaire.
*
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_is_odd(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
BigInteger a = number.get().remainder(BigIntegerMath.TWO);
return new Node(a.compareTo(BigInteger.ONE) != 0 ? Node.TRUE: Node.FALSE);
}
/**
* retourne TRUE si la valeur entière du nombre est paire.
*
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_is_even(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
BigInteger a = number.get().remainder(BigIntegerMath.TWO);
return new Node(a.compareTo(BigInteger.ONE) == 0 ? Node.TRUE: Node.FALSE);
}
/**
* retourne toujours TRUE (le nombre est toujours un entier)
*
* Cette méthode est définie pour assurer le polymorphisme.
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_is_integer(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(Node.TRUE);
}
/**
* retourne toujours FALSE (le nombre est toujours un entier).
*
* Cette méthode est définie pour assurer le polymorphisme.
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_is_decimal(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(Node.FALSE);
}
/**
* retourne un Node:nombre indiquant le nombre de chiffres (puissance de 10 du Decimal).
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_digits10(Node startAt) throws Exception {
return new Node(BigIntegerMath.digits10(number.get()));
}
/**
* Retourne la valeur du bit dont les positions est fournie.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_is_bit(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
return new Node(number.get().testBit((int) startAt.getSubNode(1, Node.TYPE_NUMBER).getNumber()) ? Node.TRUE: Node.FALSE);
}
/**
* Retourne le nombre de bits minimum pour représenter le nombre.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_digits2(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return new Node(number.get().bitLength());
}
/**
* Retourne un Integer dans lequel les bits dont les positions sont fournies en argument ont été placés à 1.
*
* Les types d'entrées supportées sont: number
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_set_bits(Node startAt) throws Exception {
startAt.isGoodArgsLength(false, 2);
BigInteger r = number.get();
for (int i = 1; i < startAt.size(); i++) {
r = r.setBit((int) startAt.getSubNode(i, Node.TYPE_NUMBER).getNumber());
}
return Node.createExternal(new External_Integer(r));
}
/**
* Place les bits dont la position est idiquée à 1 dans l' Integer courrant.
*
* Les types d'entrées supportées sont: number
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_set_bits(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
int[] bits = new int[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
bits[i - 1] = (int) startAt.getSubNode(i, Node.TYPE_NUMBER).getNumber();
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < bits.length; i++)
r = r.setBit(bits[i]);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* Place les bits dont la position est idiquée à 1 dans l' Integer courrant.
*
* Comme il s'agit d'une fonction fetch-and-*, la valeur de l'entier est retournée
* dans son état d'avant la modificetion.
*
* Les types d'entrées supportées sont: number
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_fetch_and_set_bits(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
int[] bits = new int[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
bits[i - 1] = (int) startAt.getSubNode(i, Node.TYPE_NUMBER).getNumber();
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < bits.length; i++)
r = r.setBit(bits[i]);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* Retourne un Integer dans lequel les bits dont les positions sont fournies en argument ont été placés à 0.
*
* Les types d'entrées supportées sont: number
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_clear_bits(Node startAt) throws Exception {
startAt.isGoodArgsLength(false, 2);
BigInteger r = number.get();
for (int i = 1; i < startAt.size(); i++) {
r = r.clearBit((int) startAt.getSubNode(i, Node.TYPE_NUMBER).getNumber());
}
return Node.createExternal(new External_Integer(r));
}
/**
* Place les bits dont la position est idiquée à 1 dans l' Integer courrant.
*
* Les types d'entrées supportées sont: number
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_clear_bits(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
int[] bits = new int[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
bits[i - 1] = (int) startAt.getSubNode(i, Node.TYPE_NUMBER).getNumber();
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < bits.length; i++)
r = r.clearBit(bits[i]);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* Place les bits dont la position est idiquée à 1 dans l' Integer courrant.
*
* Les types d'entrées supportées sont: number
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_fetch_and_clear_bits(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
int[] bits = new int[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
bits[i - 1] = (int) startAt.getSubNode(i, Node.TYPE_NUMBER).getNumber();
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < bits.length; i++)
r = r.clearBit(bits[i]);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* Retourne la somme du Integer courant ajouté de la liste de valeurs qui peuvent être des Nodes.
*
* Les types d'entrées supportées sont: number, string, Integer, Decimal.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_add(Node startAt) throws Exception {
startAt.isGoodArgsLength(false, 2);
BigInteger r = number.get();
for (int i = 1; i < startAt.size(); i++) {
r = r.add(_getArg_(startAt, i));
}
return Node.createExternal(new External_Integer(r));
}
/**
* surcharge de l'opérateur +!
*
* Les types d'entrées supportées sont: number, string, Integer et Decimal.
*
* @param startAt
* @return
* @throws Exception
*/
public Node external_mutator_add(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < v.length; i++)
r = r.add(v[i]);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* surcharge de l'opérateur fetch&+!
*
* Les types d'entrées supportées sont: number, string, Integer et Decimal.
*
* @param startAt
* @return
* @throws Exception
*/
public Node external_mutator_fetch_and_add(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < v.length; i++)
r = r.add(v[i]);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* Retourne le produit du Integer courant multiplié par la liste des valeurs posées en arguments.
*
* Les types d'entrées supportées sont: number, string, Integer et Decimal.
*
* La méthode supporte également les arguments lazy (dont l'évaluation est paresseuse).
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mul(Node startAt) throws Exception {
startAt.isGoodArgsLength(false, 2);
BigInteger r = number.get();
if (r.signum() == 0) {
// cas ou la variable statique est déjà zéro.
return Node.createExternal(new External_Integer(BigInteger.ZERO));
}
int i = 1;
int asize = startAt.size();
while (i < asize && r.signum() != 0)
r = r.multiply(_getArg_lazy_(startAt, i++));
//System.out.println("ml:"+r.toString());
// signum() retourne 0 si r vaut 0. Cette méthode est plus rapide que compareTo()...
return Node.createExternal(new External_Integer(r));
}
/*
* Pour expérimentation... tests de debogage...
*
public Node externalpc_test(){
return Node.createEmptyList();
}
*/
/**
* surcharge de l'opérateur *!
*
* Les types d'entrées supportées sont: number, string, Integer et Decimal.
*
* La méthode supporte également les arguments lazy (dont l'évaluation est paresseuse).
*
* @param startAt
* @return
* @throws Exception
*/
public Node external_mutator_mul(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
if (number.get().signum() == 0) {
// cas ou la variable statique est déjà zéro.
return null;
}
BigInteger v = BigInteger.ONE;
int ki = 1;
while (ki < startAt.size()) {
v = v.multiply(_getArg_lazy_(startAt, ki++));
if (v.signum() == 0)
ki = startAt.size();
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
int i = 0;
r = r.multiply(v);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* Surcharge de l'opérateur fetch&*!
*
* Les types d'entrées supportées sont: number, string, Integer et Decimal.
*
* La méthode supporte également les arguments lazy (dont l'évaluation est paresseuse).
*
* @param startAt
* @return
* @throws Exception
*/
public Node external_mutator_fetch_and_mul(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
if (number.get().signum() == 0) {
// cas ou la variable statique est déjà zéro.
return Node.createExternal(new External_Integer(BigInteger.ZERO));
}
BigInteger v = BigInteger.ONE;
int ki = 1;
while (ki < startAt.size()) {
v = v.multiply(_getArg_lazy_(startAt, ki++));
if (v.signum() == 0)
ki = startAt.size();
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
r = r.multiply(v);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* Retourne le reste de la division entière de la valeur courante avec l'argument.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mod(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
try {
return Node.createExternal(new External_Integer(number.get().remainder(_getArg_(startAt, 1))));
}
catch (ArithmeticException ex) {
// prévoir la gestion de l'exception division par zéro sur exception seulement.
// c'est plus rapide car on n'a pas besoin de tester la valeur à chaque fois.
if (ex.getMessage().equals("Division by zero")) {
throw new InterpreterException(StdErrors.Division_by_zero);
}
else {
throw new InterpreterException(StdErrors.extend(StdErrors.Arithmetic_error, ex.getMessage()));
}
}
}
/**
* Retourne le résultat de la soustraction des valeurs d'entrées à partir de la valeur courante.
*
* Note: S'il n'y a pas d'arguments, la méthode retourne -n (n étant la valeur courante).
*
* Les types d'entrées supportées sont: number, string, Integer et Decimal.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_sub(Node startAt) throws Exception {
/*
* s'il n'y a pas d'arguments, on considère qu'il s'agit de l'expression (- n)...
*/
int asize = startAt.size();
if (asize == 1) {
return Node.createExternal(new External_Integer(number.get().negate()));
}
/*
* s'il y a au moins un argument, on considère la forme (- n [args...])...
*/
BigInteger r = number.get();
for (int i = 1; i < asize; )
r = r.subtract(_getArg_(startAt, i++));
return Node.createExternal(new External_Integer(r));
}
/**
* surcharge de l'opérateur -!
*
* Note: S'il n'y a pas d'arguments, la méthode effectue l'opération -n (n étant la valeur courante).
*
* Les types d'entrées supportées sont: number, string, Integer et Decimal.
*
* @param startAt
* @return
* @throws Exception
*/
public Node external_mutator_sub(Node startAt) throws Exception {
/*
* s'il n'y a pas d'arguments, on considère qu'il s'agit de l'expression (- n)...
*/
SELF.require_SELF_mutable();
int asize = startAt.size();
if (asize == 1) {
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.negate();
}
while (!number.compareAndSet(old_r, r));
return null;
}
/*
* s'il y a au moins un argument, on considère la forme (- n [args...])...
*/
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < v.length; i++)
r = r.subtract(v[i]);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* Surcharge de l'opérateur fetch&-!
*
* Note: S'il n'y a pas d'arguments, la méthode effectue l'opération -n (n étant la valeur courante).
*
* Les types d'entrées supportées sont: number, string, Integer et Decimal.
*
* @param startAt
* @return
* @throws Exception
*/
public Node external_mutator_fetch_and_sub(Node startAt) throws Exception {
/*
* s'il n'y a pas d'arguments, on considère qu'il s'agit de l'expression (- n)...
*/
SELF.require_SELF_mutable();
int asize = startAt.size();
if (asize == 1) {
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.negate();
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/*
* s'il y a au moins un argument, on considère la forme (- n [args...])...
*/
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < v.length; i++)
r = r.subtract(v[i]);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* Renvoie le résultat de la division (entière) successive des arguments à partir de la valeur courante.
*
* Note: S'il n'y à pas d'argument, la méthode retourne le résultat de l'opération 1/n (n étant la valeur courante).
*
* Les types d'entrées supportées sont : number, string, Integer et Decimal.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_div(Node startAt) throws Exception {
/*
* s'il n'y a pas d'arguments, on considère qu'il s'agit de l'expression (- n)...
*/
int asize = startAt.size();
if (asize == 1) {
BigInteger d = BigInteger.ONE;
try {
return Node.createExternal(new External_Integer(d.divide(number.get())));
}
catch (ArithmeticException ex) {
// prévoir la gestion de l'exception division par zéro sur exception seulement.
// c'est plus rapide car on n'a pas besoin de tester la valeur à chaque fois.
if (ex.getMessage().equals("Division by zero")) {
throw new InterpreterException(StdErrors.Division_by_zero);
}
else {
throw new InterpreterException(StdErrors.extend(StdErrors.Arithmetic_error, ex.getMessage()));
}
}
}
/*
* s'il y a au moins un argument, on considère la forme (- n [args...])...
*/
BigInteger r = number.get();
try {
for (int i = 1; i < asize; )
r = r.divide(_getArg_(startAt, i++));
}
catch (ArithmeticException ex) {
// prévoir la gestion de l'exception division par zéro sur exception seulement.
// c'est plus rapide car on n'a pas besoin de tester la valeur à chaque fois.
if (ex.getMessage().equals("Division by zero")) {
throw new InterpreterException(StdErrors.Division_by_zero);
}
else {
throw new InterpreterException(StdErrors.extend(StdErrors.Arithmetic_error, ex.getMessage()));
}
}
return Node.createExternal(new External_Integer(r));
}
/**
* surcharge de l'opérateur /!
*
* Note: S'il n'y à pas d'argument, la méthode effectue de l'opération 1/n (n étant la valeur courante).
*
* Les types d'entrées supportées sont : number, string, Integer et Decimal.
*
* @param startAt
* @return
* @throws Exception
*/
public Node external_mutator_div(Node startAt) throws Exception {
/*
* s'il n'y a pas d'arguments, on considère qu'il s'agit de l'expression (- n)...
*/
SELF.require_SELF_mutable();
int asize = startAt.size();
if (asize == 1) {
BigInteger d = BigInteger.ONE;
try {
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = d.divide(old_r);
}
while (!number.compareAndSet(old_r, r));
}
catch (ArithmeticException ex) {
// prévoir la gestion de l'exception division par zéro sur exception seulement.
// c'est plus rapide car on n'a pas besoin de tester la valeur à chaque fois.
if (ex.getMessage().equals("Division by zero")) {
throw new InterpreterException(StdErrors.Division_by_zero);
}
else {
throw new InterpreterException(StdErrors.extend(StdErrors.Arithmetic_error, ex.getMessage()));
}
}
return null;
}
/*
* s'il y a au moins un argument, on considère la forme (- n [args...])...
*/
try {
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < v.length; i++)
r = r.divide(v[i]);
}
while (!number.compareAndSet(old_r, r));
}
catch (ArithmeticException ex) {
// prévoir la gestion de l'exception division par zéro sur exception seulement.
// c'est plus rapide car on n'a pas besoin de tester la valeur à chaque fois.
if (ex.getMessage().equals("Division by zero")) {
throw new InterpreterException(StdErrors.Division_by_zero);
}
else {
throw new InterpreterException(StdErrors.extend(StdErrors.Arithmetic_error, ex.getMessage()));
}
}
return null;
}
/**
* surcharge de l'opérateur fetch&/!
*
* Note: S'il n'y à pas d'argument, la méthode effectue de l'opération 1/n (n étant la valeur courante).
*
* Les types d'entrées supportées sont : number, string, Integer et Decimal.
*
* @param startAt
* @return
* @throws Exception
*/
public Node external_mutator_fetch_and_div(Node startAt) throws Exception {
/*
* s'il n'y a pas d'arguments, on considère qu'il s'agit de l'expression (- n)...
*/
SELF.require_SELF_mutable();
int asize = startAt.size();
if (asize == 1) {
BigInteger d = BigInteger.ONE;
try {
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = d.divide(old_r);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
catch (ArithmeticException ex) {
// prévoir la gestion de l'exception division par zéro sur exception seulement.
// c'est plus rapide car on n'a pas besoin de tester la valeur à chaque fois.
if (ex.getMessage().equals("Division by zero")) {
throw new InterpreterException(StdErrors.Division_by_zero);
}
else {
throw new InterpreterException(StdErrors.extend(StdErrors.Arithmetic_error, ex.getMessage()));
}
}
}
/*
* s'il y a au moins un argument, on considère la forme (- n [args...])...
*/
try {
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < v.length; i++)
r = r.divide(v[i]);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
catch (ArithmeticException ex) {
// prévoir la gestion de l'exception division par zéro sur exception seulement.
// c'est plus rapide car on n'a pas besoin de tester la valeur à chaque fois.
if (ex.getMessage().equals("Division by zero")) {
throw new InterpreterException(StdErrors.Division_by_zero);
}
else {
throw new InterpreterException(StdErrors.extend(StdErrors.Arithmetic_error, ex.getMessage()));
}
}
}
/**
* Retourne l'opération AND de l'Integer courant par la liste des valeurs posées en arguments.
*
* Attention: Les arguments supportés sont convertis en Integer pour pouvoir s'appliquer à une opération bit à bit.
* ========= Ceci contraste avec l'opération (and number ...) qui accepte aussi des TRUE-équivalents...
*
* La méthode supporte également les arguments lazy (dont l'évaluation est paresseuse).
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_and(Node startAt) throws Exception {
startAt.isGoodArgsLength(false, 2);
BigInteger r = number.get();
int i = 1;
int asize = startAt.size();
while (i < asize && r.signum() != 0)
r = r.and(_getArg_lazy_(startAt, i++));
return Node.createExternal(new External_Integer(r));
}
/**
* Réalise statiquement l'opération AND de l'Integer courant par la liste des valeurs posées en arguments.
*
* Attention: Les arguments supportés sont convertis en Integer pour pouvoir s'appliquer à une opération bit à bit.
* ========= Ceci contraste avec l'opération (and number ...) qui accepte aussi des TRUE-équivalents...
*
* La méthode supporte également les arguments lazy (dont l'évaluation est paresseuse).
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_and(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
int i = 0;
while (i < v.length && r.signum() != 0)
r = r.and(v[i++]);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* surcharge de l'opérateur fetch&and!
*
* Attention: Les arguments supportés sont convertis en Integer pour pouvoir s'appliquer à une opération bit à bit.
* ========= Ceci contraste avec l'opération (and number ...) qui accepte aussi des TRUE-équivalents...
*
* La méthode supporte également les arguments lazy (dont l'évaluation est paresseuse).
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_fetch_and_and(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
int i = 0;
while (i < v.length && r.signum() != 0)
r = r.and(v[i++]);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* Retourne l'opération OR de l'Integer courant par la liste des valeurs posées en arguments.
*
* Attention: Les arguments supportés sont convertis en Integer pour pouvoir s'appliquer à une opération bit à bit.
* ========= Ceci contraste avec l'opération (and number ...) qui accepte aussi des TRUE-équivalents...
*
* La méthode NE SUPPORTE PAS les arguments lazy. Les grands nombres entiers n'ayant pas de limite de bits,
* l'opération OR ne peut s'arrêter sur un résultat fini avant l'évaluation complète de tous les arguments.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_or(Node startAt) throws Exception {
startAt.isGoodArgsLength(false, 2);
BigInteger r = number.get();
int i = 1;
int asize = startAt.size();
while (i < asize && r.signum() != 0)
r = r.or(_getArg_(startAt, i++));
return Node.createExternal(new External_Integer(r));
}
/**
* surcharge de l'opérateur or!
*
* Attention: Les arguments supportés sont convertis en Integer pour pouvoir s'appliquer à une opération bit à bit.
* ========= Ceci contraste avec l'opération (and number ...) qui accepte aussi des TRUE-équivalents...
*
* La méthode NE SUPPORTE PAS les arguments lazy. Les grands nombres entiers n'ayant pas de limite de bits,
* l'opération OR ne peut s'arrêter sur un résultat fini avant l'évaluation complète de tous les arguments.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_or(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < v.length; i++)
r = r.or(v[i]);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* surcharge de l'opérateur fetch&or!
*
* Attention: Les arguments supportés sont convertis en Integer pour pouvoir s'appliquer à une opération bit à bit.
* ========= Ceci contraste avec l'opération (and number ...) qui accepte aussi des TRUE-équivalents...
*
* La méthode NE SUPPORTE PAS les arguments lazy. Les grands nombres entiers n'ayant pas de limite de bits,
* l'opération OR ne peut s'arrêter sur un résultat fini avant l'évaluation complète de tous les arguments.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_fetch_and_or(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < v.length; i++)
r = r.or(v[i]);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* Retourne l'opération XOR de l'Integer courant par la liste des valeurs posées en arguments.
*
* Attention: Les arguments supportés sont convertis en Integer pour pouvoir s'appliquer à une opération bit à bit.
* ========= Ceci contraste avec l'opération (and number ...) qui accepte aussi des TRUE-équivalents...
*
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_xor(Node startAt) throws Exception {
startAt.isGoodArgsLength(false, 2);
BigInteger r = number.get();
int i = 1;
int asize = startAt.size();
while (i < asize)
r = BigIntegerMath.xor(r, _getArg_(startAt, i++));
return Node.createExternal(new External_Integer(r));
}
/**
* surcharge de l'opérateur xor!
*
* Attention: Les arguments supportés sont convertis en Integer pour pouvoir s'appliquer à une opération bit à bit.
* ========= Ceci contraste avec l'opération (and number ...) qui accepte aussi des TRUE-équivalents...
*
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_xor(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < v.length; i++)
r = BigIntegerMath.xor(r, v[i]);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* surcharge de l'opérateur fetch&xor!
*
* Attention: Les arguments supportés sont convertis en Integer pour pouvoir s'appliquer à une opération bit à bit.
* ========= Ceci contraste avec l'opération (and number ...) qui accepte aussi des TRUE-équivalents...
*
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_fetch_and_xor(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsLength(false, 2);
BigInteger[] v = new BigInteger[startAt.size() - 1];
for (int i = 1; i < startAt.size(); i++) {
v[i - 1] = _getArg_(startAt, i);
}
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r;
for (int i = 0; i < v.length; i++)
r = BigIntegerMath.xor(r, v[i]);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* Retourne l'opération SHIFT-L de l'Integer courant par le number (int) fourni.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_lshift(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
BigInteger r = number.get();
r = r.shiftLeft((int) startAt.getSubNode(1, Node.TYPE_NUMBER).getNumber());
return Node.createExternal(new External_Integer(r));
}
/**
* surcharge de l'opérateur lshift!
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_lshift(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsCnt(2);
int bits = (int) startAt.getSubNode(1, Node.TYPE_NUMBER).getNumber();
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.shiftLeft(bits);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* surcharge de l'opérateur fetch&lshift!
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_fetch_and_lshift(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsCnt(2);
int bits = (int) startAt.getSubNode(1, Node.TYPE_NUMBER).getNumber();
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.shiftLeft(bits);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* Retourne l'opération SHIFT-R de l'Integer courant par le number (int) fourni.
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_rshift(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
BigInteger r = number.get();
r = r.shiftRight((int) startAt.getSubNode(1, Node.TYPE_NUMBER).getNumber());
return Node.createExternal(new External_Integer(r));
}
/**
* surcharge de l'opérateur rshift!
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_rshift(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsCnt(2);
int bits = (int) startAt.getSubNode(1, Node.TYPE_NUMBER).getNumber();
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.shiftRight(bits);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* surcharge de l'opérateur fetch&rshift!
*
* @param startAt
* @return Node:Integer
* @throws Exception
*/
public Node external_mutator_fetch_and_rshift(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsCnt(2);
int bits = (int) startAt.getSubNode(1, Node.TYPE_NUMBER).getNumber();
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.shiftRight(bits);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* retourne le résultat de l'opération NOT.
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_not(Node startAt) throws Exception {
startAt.isGoodArgsCnt(1);
return Node.createExternal(new External_Integer(number.get().not()));
}
/**
* Opération NOT statique + atomique.
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_mutator_not(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsCnt(1);
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.not();
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* surcharge de l'opérateur fetch¬!
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_mutator_fetch_and_not(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsCnt(1);
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.not();
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* Opération incrémentation statique et atomique.
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_mutator_incr(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsCnt(1);
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.add(BigInteger.ONE);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* surcharge de l'opérateur fetch&incr!
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_mutator_fetch_and_incr(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsCnt(1);
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.add(BigInteger.ONE);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/**
* Opération decrémentation statique et atomique.
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_mutator_decr(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsCnt(1);
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.subtract(BigInteger.ONE);
}
while (!number.compareAndSet(old_r, r));
return null;
}
/**
* Opération decrémentation statique et atomique.
*
* @param startAt
* @return Node:number
* @throws Exception
*/
public Node external_mutator_fetch_and_decr(Node startAt) throws Exception {
SELF.require_SELF_mutable();
startAt.isGoodArgsCnt(1);
BigInteger old_r;
BigInteger r;
do {
old_r = number.get();
r = old_r.subtract(BigInteger.ONE);
}
while (!number.compareAndSet(old_r, r));
return Node.createExternal(new External_Integer(old_r));
}
/*
* ----------------------------------------------------------------------------
*
* Optimisation par cache d'instanciantion (mars 2012) rev 1.0-6321.0
*
* ----------------------------------------------------------------------------
*/
private static ORef _optim_symbols_cache_ = new ORef();
@Override
public Object getSymbolsCache() {
return _optim_symbols_cache_.getRef();
}
@Override
public void setSymbolsCache(Object cache) {
_optim_symbols_cache_.setRef(cache);
}
public void setNumber(BigInteger number) {
this.number.getAndSet(number);
}
public BigInteger getNumber() {
return number.get();
}
}