質問

(マイ)SQLのように符号なしの数値を使用するJavaでの方法はありますか?

は、例えば:私は範囲のような8ビットの変数(byte)を使用したい:0 ... 256。代わりに-128の... 127ます。

役に立ちましたか?

解決

いいえ、Javaは(事実上、値0〜65535を有する)char別に任意の符号なしのプリミティブ型を有していません。これは、(特にbyte用)の痛みだが、それはそれは方法です。

は、通常、あなたのいずれかが「高」の数字のためにネガに同じサイズ、およびオーバーフローに固執、またはより広いタイプ(shortため例えばbyte)を使用し、余分なメモリ要件に対処ます。

他のヒント

あなたは符号なしの数をシミュレートするためにクラスを使用することができます。たとえば、

public class UInt8 implements Comparable<UInt8>,Serializable
   {
   public static final short MAX_VALUE=255;
   public static final short MIN_VALUE=0;
   private short storage;//internal storage in a int 16

   public UInt8(short value)
      {
      if(value<MIN_VALUE || value>MAX_VALUE) throw new IllegalArgumentException();
      this.storage=value;
      }

   public byte toByte()
      {
      //play with the shift operator ! << 
      }
  //etc...
   }
彼らは符号なしであるかのように

あなたは、主に署名した番号を使用することができます。ほとんどの操作は同じまま、一部を変更する必要があります。 をhref="https://stackoverflow.com/questions/397867/port-of-random-generator-from-c-to-java/397997#397997">参照してください。

内部的には、あなたは小さな値を使用すべきではない - ちょうどint型を使用します。私はそれを理解し、より小さな単位を使用することは何もなく、ゆっくりと物事ダウンしません。内部的にJavaは、すべてのストレージシステムのワードサイズを使用しているため、それは(それが言葉をパックしません)メモリを節約しません。

あなたは小さいサイズのストレージユニットを使用する場合は、

しかし、それはすべての操作のためにそれらまたは範囲チェックか何かを隠すために持っています。

は、これまでのchar(任意のオペレーション)charはint型を生み出すことに気づきますか?彼らは本当にあなたがこれらの他のタイプを使用することを期待しないでください。

例外はあなたが小さいタイプが便利使用して見つけるかもしれない...しかし、マスキングが同様に動作します(私はパックされますと信じて)アレイおよびI / Oです。

いいえ、あなたはそれを変更することはできません。あなたは127よりも大きな何かが必要な場合は、バイトより大きいものを選択します。

あなたのストレージ(例えば大行列)を最適化する必要がある場合は、uがスペースを節約するので、ネガ番号で大きな正の数をコーディングすることができます。その後、あなたは必要なときに実際の値を取得するために数値をシフトする必要があります。例えば、私は短い正の数だけを操作したいです。ここでは、これはJavaで可能ですか。

        short n = 32767;
        n = (short) (n + 10);
        System.out.println(n);     
        int m = (int) (n>=0?n:n+65536); 
        System.out.println(m);
短い整数の範囲を超えたときに、

そこで、それは負になります。しかし、少なくともあなたは16ビットでこの番号を格納し、シフト値(符号化することができる異なる値の数)を加算し、その正しい値を復元することができます。値が大きい方のタイプ(私たちの場合はint型)に復元する必要があります。これは非常に便利ではないかもしれないが、私はそれが私の場合はそうだ見つけます。

I'm quite new to Java and to programming. Yet, I encountered the same situation recently the need of unsigned values.

It took me around two weeks to code everything I had in mind, but I'm a total noob, so you could spend much less.

The general idea is to create interface, I have named it: UnsignedNumber<Base, Shifted> and to extend Number.class whilst implementing an abstract AbstractUnsigned<Base, Shifted, Impl extends AbstractUnsigned<Base, Shifted, Impl>> class.

So, Base parameterized type represents the base type, Shifted represents actual Java type. Impl is a shortcut for Implementation of this abstract class.

Most of the time consumed boilerplate of Java 8 Lambdas and internal private classes and safety procedures. The important thing was to achieve the behavior of unsigned when mathematical operation like subtraction or negative addition spawns the zero limit: to overflow the upper signed limit backwards.

Finally, it took another couple of days to code factories and implementation sub classes.

So far I have know: UByte and MUByte UShort and MUShort UInt and MUInt ... Etc.

They are descendants of AbstractUnsigned: UByte or MUByte extend AbstractUnsigned<Byte, Short, UByte> or AbstractUnsigned<Byte, Short, MUByte> UShort or MUShort extend AbstractUnsigned<Short, Integer, UShort> or AbstractUnsigned<Short, Integer, MUShort> ...etc.

The general idea is to take unsigned upper limit as shifted (casted) type and code transposition of negative values as they were to come not from zero, but the unsigned upper limit.

UPDATE: (Thanks to Ajeans kind and polite directions)

/**
* Adds value to the current number and returns either
* new or this {@linkplain UnsignedNumber} instance based on
* {@linkplain #isImmutable()}
*
* @param value value to add to the current value
* @return new or same instance
* @see #isImmutable()
*/
public Impl plus(N value) {
    return updater(number.plus(convert(value)));
}

This is an externally accessible method of AbstractUnsigned<N, Shifted, Impl> (or as it was said before AbstractUnsigned<Base, Shifted, Impl>); Now, to the under-the-hood work:

private Impl updater(Shifted invalidated){
    if(mutable){
        number.setShifted(invalidated);
        return caster.apply(this);
    } else {
        return shiftedConstructor.apply(invalidated);
    }
}

In the above private method mutable is a private final boolean of an AbstractUnsigned. number is one of the internal private classes which takes care of transforming Base to Shifted and vice versa. What matters in correspondence with previous 'what I did last summer part' is two internal objects: caster and shiftedConstructor:

final private Function<UnsignedNumber<N, Shifted>, Impl> caster;
final private Function<Shifted, Impl> shiftedConstructor;

These are the parameterized functions to cast N (or Base) to Shifted or to create a new Impl instance if current implementation instance of the AbstractUnsigned<> is immutable.

Shifted plus(Shifted value){
    return spawnBelowZero.apply(summing.apply(shifted, value));
}

In this fragment is shown the adding method of the number object. The idea was to always use Shifted internally, because it is uncertain when the positive limits of 'original' type will be spawned. shifted is an internal parameterized field which bears the value of the whole AbstractUnsigned<>. The other two Function<> derivative objects are given below:

final private BinaryOperator<Shifted> summing;
final private UnaryOperator<Shifted> spawnBelowZero;

The former performs addition of two Shifted values. And the latter performs spawning below zero transposition.

And now an example from one of the factory boilerplates 'hell' for AbstractUnsigned<Byte, Short> specifically for the mentioned before spawnBelowZero UnaryOperator<Shifted>:

...,
         v-> v >= 0
         ? v
         : (short) (Math.abs(Byte.MIN_VALUE) + Byte.MAX_VALUE + 2 + v),
...

if Shifted v is positive nothing really happens and the original value is being returned. Otherwise: there's a need to calculate the upper limit of the Base type which is Byte and add up to that value negative v. If, let's say, v == -8 then Math.abs(Byte.MIN_VALUE) will produce 128 and Byte.MAX_VALUE will produce 127 which gives 255 + 1 to get the original upper limit which was cut of by the sign bit, as I got that, and the so desirable 256 is in the place. But the very first negative value is actually that 256 that's why +1 again or +2 in total. Finally, 255 + 2 + v which is -8 gives 255 + 2 + (-8) and 249

Or in a more visual way:

0 1 2 3 ... 245 246 247 248 249 250 251 252 253 254 255 256
                             -8  -7  -6  -5  -4  -3  -2  -1

And to finalize all that: this definitely does not ease your work or saves memory bytes, but you have a pretty much desirable behaviour when it is needed. And you can use that behaviour pretty much with any other Number.class subclasses. AbstractUnsigned being subclass of Number.class itself provides all the convenience methods and constants similar to other 'native' Number.class subclasses, including MIN_VALUE and MAX_VALUE and a lot more, for example, I coded convenience method for mutable subclasses called makeDivisibileBy(Number n) which performs the simplest operation of value - (value % n).

My initial endeavour here was to show that even a noob, such as I am, can code it. My initial endeavour when I was coding that class was to get conveniently versatile tool for constant using.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top