😎
真偽値の拡張
こちらの記事で作ったC#の真偽値ロジックを少し拡張しました
絶対値を導入することで、どんな数値型にも対応するように改修しています
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Linq;
using static BoolOP;
public struct Number(long number){
long _number=number;
readonly string _word;
BoolFlag Flag{get;init;}=BoolFlag.FALSE;
BoolFlag StrBool{get;init;}=BoolFlag.FALSE;
public Number(double number):this(Unsafe.As<double,long>(ref number))=>Flag=BoolFlag.TRUE;
public Number(string str):this(unchecked(str.Select(x=>(int)x).Sum()))=>(StrBool,this._word)=(BoolFlag.TRUE,str);
public object GetNumber=>new object[]{new ValueType[]{_number,Unsafe.As<long,double>(ref _number)}[(int)Flag],_word}[(int)StrBool];
public static implicit operator Number(long x)=>new(x);
public static implicit operator Number(double x)=>new(x);
public static implicit operator Number(string word)=>new(word);
public static explicit operator Type(Number num)=>new[]{new[]{typeof(long),typeof(double)}[(int)num.Flag],typeof(string)}[(int)num.StrBool];
public static implicit operator string(Number num)=>((Type)num).Name;
public static BoolFlag operator <(Number x,Number y)=>x._number.IsLittle(y._number);
public static BoolFlag operator >(Number x,Number y)=>x._number.IsBig(y._number);
public static BoolFlag operator ==(Number x,Number y)=>x._number.Equal(y._number);
public static BoolFlag operator !=(Number x,Number y)=>(BoolFlag)BoolNum(x._number-y._number);
}
public static class BoolOP{
static int ToBoolNum(BigInteger num)=>(int)((num+2)%(num+1));
static int ToBoolNum(long num)=>ToBoolNum(unchecked((ulong)num));
public static int BoolNum(BigInteger num){
BigInteger x=ToABS(num);
return (int)((x+2)%(x+1));
}
static Func<BigInteger> ABSFunc(BigInteger num){
string x=num.ToString();
return new[]{()=>BigInteger.Parse(x),new[]{()=>BigInteger.Parse(x),()=>BigInteger.Parse(x[1..])}[(int)OrEqual(x[0],'-')]}[ToBoolNum(x.Length-1)];
}
public static BigInteger ToABS(BigInteger num)=>ABSFunc(num)();
static BoolFlag OrEqual(this long x,long y)
=>(BoolFlag)(ToBoolNum((BigInteger)unchecked((ulong)x)+1)-ToBoolNum(x-y));
public static BoolFlag Equal(this long x,long y)
=>(BoolFlag)(BoolNum(ToABS(x)+1)-BoolNum(x-y));
public static BoolFlag IsBig(this long x,long y){
long seed=y-x;
BigInteger a=ToABS(seed),b=seed;
return (BoolFlag)BoolNum(a-b);
}
public static BoolFlag AsBig(this long x,long y){
int a=(int)Equal(x,y),b=(int)IsBig(x,y);
return (BoolFlag)BoolNum(a+b);
}
public static BoolFlag IsLittle(this long x,long y)=>IsBig(y,x);
public static BoolFlag AsLittle(this long x,long y)=>AsBig(y,x);
}
public enum BoolFlag:byte{
FALSE,
TRUE
}
絶対値は文字列変換した数値の最初の要素が負数演算子を持つか否かで処理を分岐させています
ここにもif
は一切登場しません
これで条件分岐を代替できるようになります
Discussion