適当Scala UByte


メモです。


テストコード生成用のC言語プログラム

```c

#include <stdio.h>

int main() {
  int i,j;
  int a[] = {0,1,2,3,126,127,128,129,253,254,255,256};
  for(i=0; i < sizeof(a)/sizeof(int); i++) {
    for(j=0; j < sizeof(a)/sizeof(int); j++) {
      printf("test(UByte(%d)<<UByte(%d)+\"\",\"%d\");\n",a[i],a[j],((unsigned char)a[i])<<((unsigned char)a[j]));
    }
  }
  return 0;
}
```

UByteを作ろうとしているメモPaseraからコピって来てて bsdライセンスなアレなので、一から作ったほうがいいのかもしれないです。

https://github.com/nystrom/scala-unsigned


```scala
import scala.math.ScalaNumber
import scala.math.ScalaNumericConversions

//@serializable
case class UByte(byteValue:Byte) {
/*
  def toUByte = UByte(intRep.toByte)
  def toUShort = UShort(intRep.toShort)
  def toUInt = UInt(intRep)
  def toULong = ULong(intRep & 0xffffffffL)

  override def byteValue = intRep.toByte
  override def shortValue = intRep.toShort*/
  def intValue: Int = byteValue.asInstanceOf[Int]
/*  override def longValue = (intRep & 0xffffffffL)
  override def floatValue = (intRep & 0xffffffffL).toFloat
  override def doubleValue = (intRep & 0xffffffffL).toDouble

  def +(x: Int): Int = this.toInt + x
  def -(x: Int): Int = this.toInt - x
  def *(x: Int): Int = this.toInt * x
  def /(x: Int): Int = this.toInt / x
  def %(x: Int): Int = this.toInt % x
  def &(x: Int): Int = this.toInt & x
  def |(x: Int): Int = this.toInt | x
  def ^(x: Int): Int = this.toInt ^ x

  def +(x: Long): Long = this.toLong + x
  def -(x: Long): Long = this.toLong - x
  def *(x: Long): Long = this.toLong * x
  def /(x: Long): Long = this.toLong / x
  def %(x: Long): Long = this.toLong % x
  def &(x: Long): Long = this.toLong & x
  def |(x: Long): Long = this.toLong | x
  def ^(x: Long): Long = this.toLong ^ x
*/
  def +(x: UByte): Int = ((byteValue & 255) + (x.byteValue & 255))
  def -(x: UByte): Int = ((byteValue & 255) - (x.byteValue & 255))
  def *(x: UByte): Int = ((byteValue & 255) * (x.byteValue & 255))
  def /(x: UByte): Int = ((byteValue & 255) / (x.byteValue & 255))
  def %(x: UByte): Int = ((byteValue & 255) % (x.byteValue & 255))
  def &(x: UByte): Int = ((byteValue & 255) & (x.byteValue & 255))
  def |(x: UByte): Int = ((byteValue & 255) | (x.byteValue & 255))
  def ^(x: UByte): Int = ((byteValue & 255) ^ (x.byteValue & 255))
  def <(x: UByte): Boolean = ((byteValue & 255) < (x.byteValue & 255))
  def >(x: UByte): Boolean = ((byteValue & 255) > (x.byteValue & 255))
  def <=(x: UByte): Boolean = ((byteValue & 255) <= (x.byteValue & 255))
  def >=(x: UByte): Boolean = ((byteValue & 255) >= (x.byteValue & 255))
  /*

  def +(x: UShort): UInt = this + x.toUInt
  def -(x: UShort): UInt = this - x.toUInt
  def *(x: UShort): UInt = this * x.toUInt
  def /(x: UShort): UInt = this / x.toUInt
  def %(x: UShort): UInt = this % x.toUInt
  def &(x: UShort): UInt = this & x.toUInt
  def |(x: UShort): UInt = this | x.toUInt
  def ^(x: UShort): UInt = this ^ x.toUInt
  def <(x: UShort): Boolean = this < x.toUInt
  def >(x: UShort): Boolean = this > x.toUInt
  def <=(x: UShort): Boolean = this <= x.toUInt
  def >=(x: UShort): Boolean = this >= x.toUInt

  def +(x: ULong): ULong = this.toULong + x
  def -(x: ULong): ULong = this.toULong - x
  def *(x: ULong): ULong = this.toULong * x
  def /(x: ULong): ULong = this.toULong / x
  def %(x: ULong): ULong = this.toULong % x
  def &(x: ULong): ULong = this.toULong & x
  def |(x: ULong): ULong = this.toULong | x
  def ^(x: ULong): ULong = this.toULong ^ x
  def <(x: ULong): Boolean = this.toULong < x
  def >(x: ULong): Boolean = this.toULong > x
  def <=(x: ULong): Boolean = this.toULong <= x
  def >=(x: ULong): Boolean = this.toULong >= x

  def +(x: UInt) = UInt(intRep + x.intRep)
  def -(x: UInt) = UInt(intRep - x.intRep)
  def *(x: UInt) = UInt(intRep * x.intRep)

  def /(x: UInt) = {
    val n = intRep & 0xffffffffL
    val m = x.intRep & 0xffffffffL
    val r = n / m
    UInt(r.toInt)
  }

  def %(x: UInt) = {
    val n = intRep & 0xffffffffL
    val m = x.intRep & 0xffffffffL
    val r = n % m
    UInt(r.toInt)
  }

  def unary_+ = this.toUInt
  def unary_- = UInt(-intRep)

  // Equality comparison to UInt is baked in

  // Override equals to allow comparison with other number types.
  // By overriding ScalaNumber, we can cause UInt.equals to be invoked when
  // comparing a number on the left with a UInt on the right.
  // This is an (undocumented?) hack and might change in the future.
  override def equals(x: Any) = x match {
    case x: SmallUInt[_] => this.toInt == x.intRep
    case x: ULong => this.toULong == x
    case x: Number => this.longValue == x.longValue && x.longValue >= 0
    case _ => false
  }
  def canEqual(x: Any) = x match {
    case _: SmallUInt[_] => true
    case _: ULong => true
    case _: Number => true
    case _ => false
  }

  private def rot(x: Int) = (x + Int.MinValue)

  def <(x: UInt) = rot(intRep) < rot(x.intRep)
  def >(x: UInt) = rot(intRep) > rot(x.intRep)
  def <=(x: UInt) = rot(intRep) <= rot(x.intRep)
  def >=(x: UInt) = rot(intRep) >= rot(x.intRep)

  def &(x : UInt) = UInt(intRep & x.intRep)
  def |(x : UInt) = UInt(intRep | x.intRep)
  def ^(x : UInt) = UInt(intRep ^ x.intRep)

  def unary_~ = UInt(~intRep)
*/
  def <<(x : Int) = UByte(byteValue << x)
  def <<(x : Long) = UByte(byteValue << x)
//  def <<(x : UInt) = UByte(byteValue << (x.toInt & 0x1f))
//  def <<(x : ULong) = UByte(byteValue << (x.toLong & 0x1f))

  def >>(x : Long) = UByte((byteValue & 255) >> x)
  def >>(x : Int) = UByte((byteValue & 255) >> x)
//  def >>(x : UInt) = UByte(byteValue >>> (x.toInt & 0x1f))
//  def >>(x : ULong) = UByte(byteValue >>> (x.toLong & 0x1f))

  def >>>(x : Int) = UByte(byteValue >>> x)
  def >>>(x : Long) = UByte(byteValue >>> x)
//  def >>>(x : UInt) = UByte(byteValue >>> (x.toInt & 0x1f))
//  def >>>(x : ULong) = UByte(byteValue >>> (x.toLong & 0x1f))

  override def toString = (byteValue & 0xff).toString
/*
  def +(x : java.lang.String) = this.toString + x

  def toHexString = (intRep & 0xffffffffL).toHexString
  def toOctalString = (intRep & 0xffffffffL).toOctalString
  def toBinaryString = (intRep & 0xffffffffL).toBinaryString
*/
}

object UByte {
  def apply(a:Int):UByte = UByte(a.asInstanceOf[Byte])
}

object t {
  implicit def int2ubyte(x: Int) = UByte(x)
  def test(b:String,s:String) {
    if (b != s) throw new Exception("test error")
  }
  def main(args:Array[String]) {
    test(UByte(0)+UByte(0)+"","0");
    test(UByte(0)+UByte(1)+"","1");
    test(UByte(0)+UByte(2)+"","2");
    test(UByte(0)+UByte(3)+"","3");
    test(UByte(0)+UByte(126)+"","126");
    test(UByte(0)+UByte(127)+"","127");
    test(UByte(0)+UByte(128)+"","128");
    test(UByte(0)+UByte(129)+"","129");
    test(UByte(0)+UByte(253)+"","253");
    test(UByte(0)+UByte(254)+"","254");
    test(UByte(0)+UByte(255)+"","255");
    test(UByte(0)+UByte(256)+"","0");
    test(UByte(1)+UByte(0)+"","1");
    test(UByte(1)+UByte(1)+"","2");
    test(UByte(1)+UByte(2)+"","3");
    test(UByte(1)+UByte(3)+"","4");
    test(UByte(1)+UByte(126)+"","127");
    test(UByte(1)+UByte(127)+"","128");
    test(UByte(1)+UByte(128)+"","129");
    test(UByte(1)+UByte(129)+"","130");
    test(UByte(1)+UByte(253)+"","254");
    test(UByte(1)+UByte(254)+"","255");
    test(UByte(1)+UByte(255)+"","256");
    test(UByte(1)+UByte(256)+"","1");
    test(UByte(2)+UByte(0)+"","2");
    test(UByte(2)+UByte(1)+"","3");
    test(UByte(2)+UByte(2)+"","4");
    test(UByte(2)+UByte(3)+"","5");
    test(UByte(2)+UByte(126)+"","128");
    test(UByte(2)+UByte(127)+"","129");
    test(UByte(2)+UByte(128)+"","130");
    test(UByte(2)+UByte(129)+"","131");
    test(UByte(2)+UByte(253)+"","255");
    test(UByte(2)+UByte(254)+"","256");
    test(UByte(2)+UByte(255)+"","257");
    test(UByte(2)+UByte(256)+"","2");
    test(UByte(3)+UByte(0)+"","3");
    test(UByte(3)+UByte(1)+"","4");
    test(UByte(3)+UByte(2)+"","5");
    test(UByte(3)+UByte(3)+"","6");
    test(UByte(3)+UByte(126)+"","129");
    test(UByte(3)+UByte(127)+"","130");
    test(UByte(3)+UByte(128)+"","131");
    test(UByte(3)+UByte(129)+"","132");
    test(UByte(3)+UByte(253)+"","256");
    test(UByte(3)+UByte(254)+"","257");
    test(UByte(3)+UByte(255)+"","258");
    test(UByte(3)+UByte(256)+"","3");
    test(UByte(126)+UByte(0)+"","126");
    test(UByte(126)+UByte(1)+"","127");
    test(UByte(126)+UByte(2)+"","128");
    test(UByte(126)+UByte(3)+"","129");
    test(UByte(126)+UByte(126)+"","252");
    test(UByte(126)+UByte(127)+"","253");
    test(UByte(126)+UByte(128)+"","254");
    test(UByte(126)+UByte(129)+"","255");
    test(UByte(126)+UByte(253)+"","379");
    test(UByte(126)+UByte(254)+"","380");
    test(UByte(126)+UByte(255)+"","381");
    test(UByte(126)+UByte(256)+"","126");
    test(UByte(127)+UByte(0)+"","127");
    test(UByte(127)+UByte(1)+"","128");
    test(UByte(127)+UByte(2)+"","129");
    test(UByte(127)+UByte(3)+"","130");
    test(UByte(127)+UByte(126)+"","253");
    test(UByte(127)+UByte(127)+"","254");
    test(UByte(127)+UByte(128)+"","255");
    test(UByte(127)+UByte(129)+"","256");
    test(UByte(127)+UByte(253)+"","380");
    test(UByte(127)+UByte(254)+"","381");
    test(UByte(127)+UByte(255)+"","382");
    test(UByte(127)+UByte(256)+"","127");
    test(UByte(128)+UByte(0)+"","128");
    test(UByte(128)+UByte(1)+"","129");
    test(UByte(128)+UByte(2)+"","130");
    test(UByte(128)+UByte(3)+"","131");
    test(UByte(128)+UByte(126)+"","254");
    test(UByte(128)+UByte(127)+"","255");
    test(UByte(128)+UByte(128)+"","256");
    test(UByte(128)+UByte(129)+"","257");
    test(UByte(128)+UByte(253)+"","381");
    test(UByte(128)+UByte(254)+"","382");
    test(UByte(128)+UByte(255)+"","383");
    test(UByte(128)+UByte(256)+"","128");
    test(UByte(129)+UByte(0)+"","129");
    test(UByte(129)+UByte(1)+"","130");
    test(UByte(129)+UByte(2)+"","131");
    test(UByte(129)+UByte(3)+"","132");
    test(UByte(129)+UByte(126)+"","255");
    test(UByte(129)+UByte(127)+"","256");
    test(UByte(129)+UByte(128)+"","257");
    test(UByte(129)+UByte(129)+"","258");
    test(UByte(129)+UByte(253)+"","382");
    test(UByte(129)+UByte(254)+"","383");
    test(UByte(129)+UByte(255)+"","384");
    test(UByte(129)+UByte(256)+"","129");
    test(UByte(253)+UByte(0)+"","253");
    test(UByte(253)+UByte(1)+"","254");
    test(UByte(253)+UByte(2)+"","255");
    test(UByte(253)+UByte(3)+"","256");
    test(UByte(253)+UByte(126)+"","379");
    test(UByte(253)+UByte(127)+"","380");
    test(UByte(253)+UByte(128)+"","381");
    test(UByte(253)+UByte(129)+"","382");
    test(UByte(253)+UByte(253)+"","506");
    test(UByte(253)+UByte(254)+"","507");
    test(UByte(253)+UByte(255)+"","508");
    test(UByte(253)+UByte(256)+"","253");
    test(UByte(254)+UByte(0)+"","254");
    test(UByte(254)+UByte(1)+"","255");
    test(UByte(254)+UByte(2)+"","256");
    test(UByte(254)+UByte(3)+"","257");
    test(UByte(254)+UByte(126)+"","380");
    test(UByte(254)+UByte(127)+"","381");
    test(UByte(254)+UByte(128)+"","382");
    test(UByte(254)+UByte(129)+"","383");
    test(UByte(254)+UByte(253)+"","507");
    test(UByte(254)+UByte(254)+"","508");
    test(UByte(254)+UByte(255)+"","509");
    test(UByte(254)+UByte(256)+"","254");
    test(UByte(255)+UByte(0)+"","255");
    test(UByte(255)+UByte(1)+"","256");
    test(UByte(255)+UByte(2)+"","257");
    test(UByte(255)+UByte(3)+"","258");
    test(UByte(255)+UByte(126)+"","381");
    test(UByte(255)+UByte(127)+"","382");
    test(UByte(255)+UByte(128)+"","383");
    test(UByte(255)+UByte(129)+"","384");
    test(UByte(255)+UByte(253)+"","508");
    test(UByte(255)+UByte(254)+"","509");
    test(UByte(255)+UByte(255)+"","510");
    test(UByte(255)+UByte(256)+"","255");
    test(UByte(256)+UByte(0)+"","0");
    test(UByte(256)+UByte(1)+"","1");
    test(UByte(256)+UByte(2)+"","2");
    test(UByte(256)+UByte(3)+"","3");
    test(UByte(256)+UByte(126)+"","126");
    test(UByte(256)+UByte(127)+"","127");
    test(UByte(256)+UByte(128)+"","128");
    test(UByte(256)+UByte(129)+"","129");
    test(UByte(256)+UByte(253)+"","253");
    test(UByte(256)+UByte(254)+"","254");
    test(UByte(256)+UByte(255)+"","255");
    test(UByte(256)+UByte(256)+"","0");
  }
}
```