com.jogamp.gluegen.jcpp.NumericValue Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gluegen-rt-android Show documentation
Show all versions of gluegen-rt-android Show documentation
JNI binding generator (Android runtime)
The newest version!
/*
* Anarres C Preprocessor
* Copyright (c) 2007-2008, Shevek
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.jogamp.gluegen.jcpp;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.annotation.CheckForNull;
import javax.annotation.CheckForSigned;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
public class NumericValue extends Number {
public static final int F_UNSIGNED = 1;
public static final int F_INT = 2;
public static final int F_LONG = 4;
public static final int F_LONGLONG = 8;
public static final int F_FLOAT = 16;
public static final int F_DOUBLE = 32;
public static final int FF_SIZE = F_INT | F_LONG | F_LONGLONG | F_FLOAT | F_DOUBLE;
private final int base;
private final String integer;
private String fraction;
private int expbase = 0;
private String exponent;
private int flags;
public NumericValue(int base, String integer) {
this.base = base;
this.integer = integer;
}
@Nonnegative
public int getBase() {
return base;
}
@Nonnull
public String getIntegerPart() {
return integer;
}
@CheckForNull
public String getFractionalPart() {
return fraction;
}
/* pp */ void setFractionalPart(String fraction) {
this.fraction = fraction;
}
@CheckForSigned
public int getExponentBase() {
return expbase;
}
@CheckForNull
public String getExponent() {
return exponent;
}
/* pp */ void setExponent(int expbase, String exponent) {
this.expbase = expbase;
this.exponent = exponent;
}
public int getFlags() {
return flags;
}
/* pp */ void setFlags(int flags) {
this.flags = flags;
}
/**
* So, it turns out that parsing arbitrary bases into arbitrary
* precision numbers is nontrivial, and this routine gets it wrong
* in many important cases.
*/
@Nonnull
public BigDecimal toBigDecimal() {
int scale = 0;
String text = getIntegerPart();
String t_fraction = getFractionalPart();
if (t_fraction != null) {
text += getFractionalPart();
// XXX Wrong for anything but base 10.
scale += t_fraction.length();
}
String t_exponent = getExponent();
if (t_exponent != null)
scale -= Integer.parseInt(t_exponent);
BigInteger unscaled = new BigInteger(text, getBase());
return new BigDecimal(unscaled, scale);
}
@Nonnull
public Number toJavaLangNumber() {
int flags = getFlags();
if ((flags & F_DOUBLE) != 0)
return doubleValue();
else if ((flags & F_FLOAT) != 0)
return floatValue();
else if ((flags & (F_LONG | F_LONGLONG)) != 0)
return longValue();
else if ((flags & F_INT) != 0)
return intValue();
else if (getFractionalPart() != null)
return doubleValue(); // .1 is a double in Java.
else if (getExponent() != null)
return doubleValue();
else
return intValue();
}
private int exponentValue() {
return Integer.parseInt(exponent, 10);
}
@Override
public int intValue() {
int v = integer.isEmpty() ? 0 : Integer.parseInt(integer, base);
if (expbase == 2)
v = v << exponentValue();
else if (expbase != 0)
v = (int) (v * Math.pow(expbase, exponentValue()));
return v;
}
@Override
public long longValue() {
long v = integer.isEmpty() ? 0 : Long.parseLong(integer, base);
if (expbase == 2)
v = v << exponentValue();
else if (expbase != 0)
v = (long) (v * Math.pow(expbase, exponentValue()));
return v;
}
@Override
public float floatValue() {
if (getBase() != 10)
return longValue();
return Float.parseFloat(toString());
}
@Override
public double doubleValue() {
if (getBase() != 10)
return longValue();
return Double.parseDouble(toString());
}
private boolean appendFlags(StringBuilder buf, String suffix, int flag) {
if ((getFlags() & flag) != flag)
return false;
buf.append(suffix);
return true;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
switch (base) {
case 8:
buf.append('0');
break;
case 10:
break;
case 16:
buf.append("0x");
break;
case 2:
buf.append('b');
break;
default:
buf.append("[base-").append(base).append("]");
break;
}
buf.append(getIntegerPart());
if (getFractionalPart() != null)
buf.append('.').append(getFractionalPart());
if (getExponent() != null) {
buf.append(base > 10 ? 'p' : 'e');
buf.append(getExponent());
}
/*
if (appendFlags(buf, "ui", F_UNSIGNED | F_INT));
else if (appendFlags(buf, "ul", F_UNSIGNED | F_LONG));
else if (appendFlags(buf, "ull", F_UNSIGNED | F_LONGLONG));
else if (appendFlags(buf, "i", F_INT));
else if (appendFlags(buf, "l", F_LONG));
else if (appendFlags(buf, "ll", F_LONGLONG));
else if (appendFlags(buf, "f", F_FLOAT));
else if (appendFlags(buf, "d", F_DOUBLE));
*/
return buf.toString();
}
}