Open11

使いそうなVerseコード備忘

aiiroIndyaiiroIndy
# message型に変換
ToMessage<public><localizes>(Text:string)<transacts>:message = "{Text}"
ToMessage<public><localizes>(Agent:agent)<transacts>:message = "{Agent}"
ToMessage<public><localizes>(Text1:string, Agent:agent, Text2:string)<transacts>:message = "{Text1}{Agent}{Text2}"

# message型の連結
operator'+'<public><localizes>(V1:message, V2:message)<transacts>:message = "{V1}{V2}"
ConcatenateMessage<localizes>(V1:message, V2:message):message = "{V1}{V2}"
ConcatenateMessage<public>(Messages:[]message, Separator:string):message =
    var ConcatenatedMessage:message = ToMessage("")
    for(Index -> Message:Messages):
        if(Index = 0):
            set ConcatenatedMessage = Message + ToMessage(Separator)
        else if(Index < Messages.Length - 1):
            set ConcatenatedMessage = ConcatenatedMessage + Message
        else:
            set ConcatenatedMessage = ConcatenatedMessage + Message + ToMessage(Separator)
    ConcatenatedMessage


# agent型をstringに変換
ToMessage<public><localizes>(Agent:agent)<transacts>:message = "{Agent}"
ToString<public>(Agent:agent):string = "{Localize(ToMessage(Agent))}"

[Output Log]

LogVerse: : Anonymous[256]

agent型をmessage型にするとプレイヤー名を取得できる。ただ、message型のままではログに出力できない。ログ出力するには、message型をstring型にすることが必要。
プレイヤー名そのものではなくなるが、デバッグ時に活躍..するかもしれない。

aiiroIndyaiiroIndy
# 絶対値。Sqrt()
var Number:float = 0.0
SqrtResult:float = Sqrt(Pow(Number, 2.0))

# 絶対値。Abs()
var FloatNumber:float = 0.0
var IntNumber:int = 0
AbsResult:float = Abs(FloatNumber)
AbsResult2:int = Abs(IntNumber)
aiiroIndyaiiroIndy
timer_sample
# 10秒計測する。
# 計測完了時、または入力用トリガーが実行されたときに計測を終了し、出力用トリガーを実行する。
timer_sample := class(creative_device):
    @editable
    Button:button_device = button_device{}
    @editable
    In_EndTrigger:trigger_device = trigger_device{}  # 入力用。トリガーされると計測を終了する。
    @editable
    Out_EndTrigger:trigger_device = trigger_device{}  # 出力用。計測の終了時にトリガーする。

    var StopEventMap:[player]event(float) = map{}  # 各プレイヤーの計測終了イベント。
    var TimerRunnningMap:[player]float = map{}  # 各プレイヤーの計測中の時間

    OnBegin<override>()<suspends>:void=
        Button.InteractedWithEvent.Subscribe(OnInteractedWith)

        for (Player : GetPlayspace().GetPlayers()):
            if:
                set StopEventMap[Player] = event(float){}
                MyStopEvent := StopEventMap[Player]
            then:
                spawn{ AwaitStop(Player, MyStopEvent) }
           
    OnInteractedWith(Agent:agent):void=
        spawn{ Running(Agent) }

    AwaitStop(Agent:agent, MyStopEvent:event(float))<suspends>:void=
        loop:
            FinishTime := MyStopEvent.Await()
            Out_EndTrigger.Trigger(Agent)
            Print("AwaitStop() FinishTime={FinishTime}")

    Running(Agent:agent)<suspends>:void=
        TargetTime := 10.0
        if (set TimerRunnningMap[player[Agent]] = 0.0){}
        Winner := race:
            block:
                loop:
                    Sleep(1.0)
                    if:
                        set TimerRunnningMap[player[Agent]] += 1.0
                        NewRunningTime := TimerRunnningMap[player[Agent]]
                    then:
                        Print("Running() NewRunningTime={NewRunningTime}")
                        if (NewRunningTime >= TargetTime):
                            break
                "Timer Over"

            block:
                In_EndTrigger.TriggeredEvent.Await()
                "In_EndTrigger Triggered"
            
        if:
            MyStopEvent := StopEventMap[player[Agent]]
            MyRunnningTime := TimerRunnningMap[player[Agent]]
        then:
            Print("Running() Winner={Winner}, {MyRunnningTime}")
            MyStopEvent.Signal(MyRunnningTime)

上記コードでは、同じプレイヤーがボタンを連続で押したときに正常に動作しないので修正。

  • プレイヤーのタイマーが実行中でない場合に、タイマーを実行する
  • トリガーがほかのデバイスと連携しやすいため、タイマーを起動するにはボタンではなくトリガーを使用する
# 10秒計測する。
# 計測完了時、またはIn_EndTriggerがトリガーされたときに計測を終了し、Out_EndTriggerをトリガーする。
timer_sample := class(creative_device):
    @editable
    In_StartTrigger:trigger_device = trigger_device{}  # 入力用。トリガーされると計測開始する。
    @editable
    In_EndTrigger:trigger_device = trigger_device{}  # 入力用。トリガーされると計測終了する。
    @editable
    Out_EndTrigger:trigger_device = trigger_device{}  # 出力用。計測の終了時にトリガーする。

    var StopEventMap:[player]event(float) = map{}  # 各プレイヤーの計測終了イベント
    var RunningTimeMap:[player]float = map{}  # 各プレイヤーの計測中の時間
    var IsRunningMap:[player]logic = map{}  # 各プレイヤーの計測中状態

    OnBegin<override>()<suspends>:void=
        In_StartTrigger.TriggeredEvent.Subscribe(OnStartTriggered)

        for (Player : GetPlayspace().GetPlayers()):
            if (set IsRunningMap[Player] = false){}
            if:
                set StopEventMap[Player] = event(float){}
                MyStopEvent := StopEventMap[Player]
            then:
                spawn{ AwaitStop(Player, MyStopEvent) }

    OnStartTriggered(AgentOpt:?agent):void=
        if:
            Agent := AgentOpt?
            not IsRunningMap[player[Agent]]?
        then:
            spawn{ Running(Agent) }
        else:
            Print("OnStartTriggered() Already Running")    

    AwaitStop(Agent:agent, MyStopEvent:event(float))<suspends>:void=
        loop:
            FinishTime := MyStopEvent.Await()
            Out_EndTrigger.Trigger(Agent)
            if (set IsRunningMap[player[Agent]] = false){}
            Print("AwaitStop() FinishTime={FinishTime}")

    Running(Agent:agent)<suspends>:void=
        if (set IsRunningMap[player[Agent]] = true){}
        TargetTime := 10.0
        if (set RunningTimeMap[player[Agent]] = 0.0){}
        Winner := race:
            block:
                loop:
                    Sleep(1.0)
                    if:
                        set RunningTimeMap[player[Agent]] += 1.0
                        NewRunningTime := RunningTimeMap[player[Agent]]
                    then:
                        Print("Running() NewRunningTime={NewRunningTime}")
                        if (NewRunningTime >= TargetTime):
                            break
                "Timer Over"

            block:
                In_EndTrigger.TriggeredEvent.Await()
                "In_EndTrigger Triggered"
            
        if:
            MyStopEvent := StopEventMap[player[Agent]]
            MyRunnningTime := RunningTimeMap[player[Agent]]
        then:
            Print("Running() Winner={Winner}, {MyRunnningTime}")
            MyStopEvent.Signal(MyRunnningTime)
aiiroIndyaiiroIndy
minimum_canvas.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Fortnite.com/UI }

#最小限のキャンバス
minimum_canvas := class(creative_device):

    @editable
    In_RemoveUIChannel:channel_device = channel_device{}
    @editable
    ShowUIButton:button_device = button_device{}

    var MainWidgetMap:[agent]?canvas = map{}

    OnBegin<override>()<suspends>:void=
        ShowUIButton.InteractedWithEvent.Subscribe(OnInteractedWith)
        In_RemoveUIChannel.ReceivedTransmitEvent.Subscribe(OnReceivedTransmit)

    OnInteractedWith(Agent:agent):void=
        if(PlayerUI := GetPlayerUI[player[Agent]]):
            if(MainWidget := MainWidgetMap[Agent]?):
                Print("OnInteractedWith() MainWidget is not false. Remove widget.")
                PlayerUI.RemoveWidget(MainWidget)
                if(set MainWidgetMap[Agent] = false){}

            else:
                Print("OnInteractedWith() MainWidget is false")

            Canvas := CreateUI()
            PlayerUI.AddWidget(Canvas, player_ui_slot{InputMode := ui_input_mode.All})
            # PlayerUI.AddWidget(Canvas)
            if(set MainWidgetMap[Agent] = option{Canvas}){}

    CreateUI():canvas=
        canvas:
            Slots := array:
                canvas_slot:
                    Anchors := anchors{
                        Minimum := vector2{X := 0.5, Y := 0.9}, 
                        Maximum := vector2{X := 0.5, Y := 0.9}
                        }
                    Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
                    Alignment := vector2{X := 0.5, Y := 0.5}
                    SizeToContent := true
                    Widget := button_loud{DefaultText := ToMessage("Button Text")}

    OnReceivedTransmit(AgentOpt:?agent):void=
        if(Agent := AgentOpt?, PlayerUI := GetPlayerUI[player[Agent]]):
            if(MainWidget := MainWidgetMap[Agent]?):
                Print("OnReceivedTransmit() MainWidget is not false. Remove widget.")
                PlayerUI.RemoveWidget(MainWidget)
                if(set MainWidgetMap[Agent] = false){}

    ToMessage<public><localizes>(Text:string)<transacts>:message = "{Text}"
aiiroIndyaiiroIndy
# 小数部2桁になるように四捨五入して、文字列に変換
FloatToDec2StringRound<public>(Number:float)<transacts>:string=
    var RetValue:string = "" 
    NumberString := ToString(Number)
    Print("FloatToDec2String() NumberString={NumberString} Length={NumberString.Length}")
    if:
        Num1:float = Number * 100  # 123.456789
        Num1Round:int = Round[Num1] # 123
        Num2:float = Num1Round * 1.0 / 100.0 # 1.23
    then:
        Print("FloatToDec2String() {Num1}, {Num1Round}, {Num2}")
        Num2String := ToString(Num2)
        if:
            ElementIdx := Num2String.Find['.']
            NewString := NumberString.Slice[0, ElementIdx+3]

        then:
            Print("FloatToDec2String() ElementIdx={ElementIdx} NewString={NewString}")
            set RetValue = NewString

    RetValue
aiiroIndyaiiroIndy

Int 関数とFloor 関数の違い

負の値で差が出た
-123.01
⇒Int関数: -123
⇒Floor関数: -124

処理

# 小数部2桁になるように切り捨てして、文字列に変換
FormatTo2Decimals<public>(Number:float)<transacts>:void=
    NumberString:string = ToString(Number)  #(例)1.2301 ⇒ "1.230100", "-1.230100"
    if:
        Num1:float = Number * 100  #(例)123.01, -123.01
        Num1Int:int = Int[Num1]  #(例)123, -123
        Num1Floor:int = Floor[Num1]  #(例)123, -124
        
    then:
        Print("FormatTo2Decimals()  NumberString={NumberString}, Length={NumberString.Length}, Number*100={Num1}")
        Num2:float = Num1Int * 1.0 / 100.0  #(例)1.23, -1.23
        Num3:float = Num1Floor * 1.0 / 100.0  #(例)1.23, -1.24

        Print("FormatTo2Decimals()  Int関数   {Num1Int}, {Num2}")
        Print("FormatTo2Decimals()  Floor関数 {Num1Floor}, {Num3}")

呼び出し側

OnBegin<override>():void=
    block:
        Number := 1.230
        Print("#FormatTo2Decimals() {Number}, {-Number}---------------------------------------------------------")
        FormatTo2Decimals(Number)
        FormatTo2Decimals(-Number)
    block:
        Number := 1.231
        Print("#FormatTo2Decimals() {Number}, {-Number}---------------------------------------------------------")
        FormatTo2Decimals(Number)
        FormatTo2Decimals(-Number)
    block:
        Number := 1.2301
        Print("#FormatTo2Decimals() {Number}, {-Number}---------------------------------------------------------")
        FormatTo2Decimals(Number)
        FormatTo2Decimals(-Number)

出力ログ

LogVerse: : #FormatTo2Decimals() 1.230000, -1.230000---------------------------------------------------------
LogVerse: : FormatTo2Decimals()  NumberString=1.230000, Length=8, Number*100=123.000000
LogVerse: : FormatTo2Decimals()  Int関数   123, 1.230000
LogVerse: : FormatTo2Decimals()  Floor関数 123, 1.230000
LogVerse: : FormatTo2Decimals()  NumberString=-1.230000, Length=9, Number*100=-123.000000
LogVerse: : FormatTo2Decimals()  Int関数   -123, -1.230000
LogVerse: : FormatTo2Decimals()  Floor関数 -123, -1.230000
LogVerse: : #FormatTo2Decimals() 1.231000, -1.231000---------------------------------------------------------
LogVerse: : FormatTo2Decimals()  NumberString=1.231000, Length=8, Number*100=123.100000
LogVerse: : FormatTo2Decimals()  Int関数   123, 1.230000
LogVerse: : FormatTo2Decimals()  Floor関数 123, 1.230000
LogVerse: : FormatTo2Decimals()  NumberString=-1.231000, Length=9, Number*100=-123.100000
LogVerse: : FormatTo2Decimals()  Int関数   -123, -1.230000
LogVerse: : FormatTo2Decimals()  Floor関数 -124, -1.240000
LogVerse: : #FormatTo2Decimals() 1.230100, -1.230100---------------------------------------------------------
LogVerse: : FormatTo2Decimals()  NumberString=1.230100, Length=8, Number*100=123.010000
LogVerse: : FormatTo2Decimals()  Int関数   123, 1.230000
LogVerse: : FormatTo2Decimals()  Floor関数 123, 1.230000
LogVerse: : FormatTo2Decimals()  NumberString=-1.230100, Length=9, Number*100=-123.010000
LogVerse: : FormatTo2Decimals()  Int関数   -123, -1.230000
LogVerse: : FormatTo2Decimals()  Floor関数 -124, -1.240000
aiiroIndyaiiroIndy

端数処理の関数

# Returns the smallest int that is greater than or equal to Val.
# Fails if not IsFinite(Val).
# Val 以上の最小の int を返します。
# IsFinite(Val) でない場合は失敗します。
Ceil<native><public>(Val:float)<computes><decides><reads>:int

# Returns the largest int that is less than or equal to Val.
# Fails if not IsFinite(Val).
# Val 以下の最大の int を返します。
# IsFinite(Val) でない場合は失敗します。
Floor<native><public>(Val:float)<computes><decides><reads>:int

# Returns Val rounded to the nearest int. When the fractional part of Val is 0.5, rounds to the nearest even int (per the IEEE-754 default rounding mode).
# Fails if not IsFinite(Val).
# 最も近い int に丸められた Val を返します。Val の小数部分が 0.5 の場合、最も近い偶数 int に丸められます (IEEE-754 のデフォルトの丸めモードに従って)。
# IsFinite(Val) でない場合は失敗します。
Round<native><public>(Val:float)<computes><decides><reads>:int

# Returns the int that equals Val without the fractional part.
# Fails if not IsFinite(val).
# 小数部を除いた Val と等しい int を返します。
# IsFinite(val) でない場合は失敗します。
Int<native><public>(Val:float)<computes><decides><reads>:int
aiiroIndyaiiroIndy

端数処理の関数について

# 端数処理の出力
PrintRounding<public>(Number:float)<transacts>:void=
    NumberString:string = ToString(Number)
    Print("NumberString={NumberString}")

    if:
        NumCeil:int = Ceil[Number]   
        NumFloor:int = Floor[Number]    
        NumRound:int = Round[Number]  
        NumInt:int = Int[Number]  

    then:
        Print("Ceil関数    {NumCeil}")
        Print("Floor関数   {NumFloor}")
        Print("Round関数   {NumRound}")
        Print("Int関数     {NumInt}")

出力ログ
LogVerse: : #PrintRounding() 3.700000---------------------------------------------------------
LogVerse: : NumberString=3.700000
LogVerse: : Ceil関数    4
LogVerse: : Floor関数   3
LogVerse: : Round関数   4
LogVerse: : Int関数     3
LogVerse: : #PrintRounding() 3.200000---------------------------------------------------------
LogVerse: : NumberString=3.200000
LogVerse: : Ceil関数    4
LogVerse: : Floor関数   3
LogVerse: : Round関数   3
LogVerse: : Int関数     3
LogVerse: : #PrintRounding() -3.700000---------------------------------------------------------
LogVerse: : NumberString=-3.700000
LogVerse: : Ceil関数    -3
LogVerse: : Floor関数   -4
LogVerse: : Round関数   -4
LogVerse: : Int関数     -3
LogVerse: : #PrintRounding() -3.200000---------------------------------------------------------
LogVerse: : NumberString=-3.200000
LogVerse: : Ceil関数    -3
LogVerse: : Floor関数   -4
LogVerse: : Round関数   -3
LogVerse: : Int関数     -3
LogVerse: : #PrintRounding() 0.500000---------------------------------------------------------
LogVerse: : NumberString=0.500000
LogVerse: : Ceil関数    1
LogVerse: : Floor関数   0
LogVerse: : Round関数   0
LogVerse: : Int関数     0
LogVerse: : #PrintRounding() 1.500000---------------------------------------------------------
LogVerse: : NumberString=1.500000
LogVerse: : Ceil関数    2
LogVerse: : Floor関数   1
LogVerse: : Round関数   2
LogVerse: : Int関数     1
LogVerse: : #PrintRounding() -0.500000---------------------------------------------------------
LogVerse: : NumberString=-0.500000
LogVerse: : Ceil関数    0
LogVerse: : Floor関数   -1
LogVerse: : Round関数   0
LogVerse: : Int関数     0
LogVerse: : #PrintRounding() -1.500000---------------------------------------------------------
LogVerse: : NumberString=-1.500000
LogVerse: : Ceil関数    -1
LogVerse: : Floor関数   -2
LogVerse: : Round関数   -2
LogVerse: : Int関数     -1

まとめ

端数処理の関数の出力結果

3.7 3.2 -3.7 -3.2 1.5 0.5 -1.5 -0.5
Ceil関数 4 4 -3 -3 2 1 -1 0
Floor関数 3 3 -4 -4 1 0 -2 -1
Round関数 4 3 -4 -3 2 0 -2 0
Int関数 3 3 -3 -3 1 0 -1 0

Ceil関数:
 常に上の整数に切り上げ。(入力値以上の最小の整数を取得)
Floor関数:
 常に下の整数に切り下げ。(入力値以下の最大の整数を取得)
Round関数:
 最も近い整数に丸める(0.5の場合は偶数に丸める特殊ルール。※IEEE-754の標準)
Int関数:
 単純に小数点以下を切り捨て。
 ただし、負の数の扱いが Floor とは異なる(例: -3.7 → Int:-3, Floor:-4)

aiiroIndyaiiroIndy

小数部第2位までの文字列に変換

Ceil, Floor, Round, Int関数で端数処理後、string型をSliceする

# 小数部第2位までの文字列に変換
FormatTo2Decimals<public>(Number:float)<transacts>:void=
    NumberString:string = ToString(Number)  #(例)1.2301 ⇒ "1.230100", "-1.230100"
    Num1:float = Number * 100 
    if:
        Num1Ceil:int = Ceil[Num1]  
        Num1Floor:int = Floor[Num1]  
        Num1Round:int = Round[Num1]  
        Num1Int:int = Int[Num1]  

    then:
        FloatAfterCeil:float = Num1Ceil * 1.0 / 100.0
        FloatAfterFloor:float = Num1Floor * 1.0 / 100.0
        FloatAfterRound:float = Num1Round * 1.0 / 100.0 
        FloatAfterInt:float = Num1Int * 1.0 / 100.0 
        if:
            DecimalPointIdx := NumberString.Find['.']
            CeilString:string = "{FloatAfterCeil}".Slice[0, DecimalPointIdx+3]
            FloorString:string = "{FloatAfterFloor}".Slice[0, DecimalPointIdx+3]
            RoundString:string = "{FloatAfterRound}".Slice[0, DecimalPointIdx+3]
            IntString:string = "{FloatAfterInt}".Slice[0, DecimalPointIdx+3]

        then:
            Print("FormatTo2Decimals()  NumberString={NumberString}, Length={NumberString.Length}, Number*100={Num1}, DecimalPointIdx={DecimalPointIdx}")
            Print("FormatTo2Decimals()  Ceil関数   {Num1Ceil}, {FloatAfterCeil}, {CeilString}")
            Print("FormatTo2Decimals()  Floor関数  {Num1Floor}, {FloatAfterFloor}, {FloorString}")
            Print("FormatTo2Decimals()  Round関数  {Num1Round}, {FloatAfterRound}, {RoundString}")
            Print("FormatTo2Decimals()  Int関数    {Num1Int}, {FloatAfterInt}, {IntString}")

出力ログ

LogVerse: : #FormatTo2Decimals() 1.232000---------------------------------------------------------
LogVerse: : FormatTo2Decimals()  NumberString=1.232000, Length=8, Number*100=123.200000, DecimalPointIdx=1
LogVerse: : FormatTo2Decimals()  Ceil関数   124, 1.240000, 1.24
LogVerse: : FormatTo2Decimals()  Floor関数  123, 1.230000, 1.23
LogVerse: : FormatTo2Decimals()  Round関数  123, 1.230000, 1.23
LogVerse: : FormatTo2Decimals()  Int関数    123, 1.230000, 1.23
LogVerse: : #FormatTo2Decimals() 1.237000---------------------------------------------------------
LogVerse: : FormatTo2Decimals()  NumberString=1.237000, Length=8, Number*100=123.700000, DecimalPointIdx=1
LogVerse: : FormatTo2Decimals()  Ceil関数   124, 1.240000, 1.24
LogVerse: : FormatTo2Decimals()  Floor関数  123, 1.230000, 1.23
LogVerse: : FormatTo2Decimals()  Round関数  124, 1.240000, 1.24
LogVerse: : FormatTo2Decimals()  Int関数    123, 1.230000, 1.23
LogVerse: : #FormatTo2Decimals() -1.232000---------------------------------------------------------
LogVerse: : FormatTo2Decimals()  NumberString=-1.232000, Length=9, Number*100=-123.200000, DecimalPointIdx=2
LogVerse: : FormatTo2Decimals()  Ceil関数   -123, -1.230000, -1.23
LogVerse: : FormatTo2Decimals()  Floor関数  -124, -1.240000, -1.24
LogVerse: : FormatTo2Decimals()  Round関数  -123, -1.230000, -1.23
LogVerse: : FormatTo2Decimals()  Int関数    -123, -1.230000, -1.23
LogVerse: : #FormatTo2Decimals() -1.237000---------------------------------------------------------
LogVerse: : FormatTo2Decimals()  NumberString=-1.237000, Length=9, Number*100=-123.700000, DecimalPointIdx=2
LogVerse: : FormatTo2Decimals()  Ceil関数   -123, -1.230000, -1.23
LogVerse: : FormatTo2Decimals()  Floor関数  -124, -1.240000, -1.24
LogVerse: : FormatTo2Decimals()  Round関数  -124, -1.240000, -1.24
LogVerse: : FormatTo2Decimals()  Int関数    -123, -1.230000, -1.23
aiiroIndyaiiroIndy

3文字ずつカンマを挿入

FormatWithCommas<public>(Number:int)<transacts>:string=
    # 文字列に変換
    NumberString := ToString(Number)
    var RetVal:string = NumberString

    # 負の数かチェック。負の数の場合、開始位置を1ずらす
    var StartIdx:int = 0
    if(NumberString[0] = '-'):
        set StartIdx = 1

    Length:int = NumberString.Length

    if:
        # カンマの数を計算
        NumCommas:int = Floor[(Length - StartIdx - 1) *1.0 / 3.0]
    then:
        # 末尾から3文字ずつカンマを挿入
        for(I := 0..NumCommas - 1):
            InsertPos := Length - (I * 3) - 3
            if:
                InsertPos > StartIdx
                NewString := RetVal.Insert[InsertPos, ","]
                set RetVal = NewString
    RetVal
aiiroIndyaiiroIndy

整数を桁数に応じてK,M,B,Tに変換。小数第2位まで取得。

# 整数を桁数に応じてK,M,B,Tに変換。小数第2位まで取得。
FormatWithUnit<public>(Number:int)<transacts>:string=
    var FloatVal:float = 0.0

    if(Number < 1000): #~999 
        return ToString(Number)

    # 1M未満の場合はK
    if(Number < 1000000): #~999,999
        set FloatVal = Number * 1.0 / 1000.0
        return FloatToDec2String(FloatVal) + "K"

    # 1B未満の場合はM
    if(Number < 1000000000): #~999,999,999
        set FloatVal = Number * 1.0 / 1000000.0
        return FloatToDec2String(FloatVal) + "M"

    # 1T未満の場合はB
    if(Number < 1000000000000): #~999,999,999,999
        set FloatVal = Number * 1.0 / 1000000000.0
        return FloatToDec2String(FloatVal) + "B"
    
    set FloatVal = Number * 1.0 / 1000000000000.0
    return FloatToDec2String(FloatVal) + "T"

# 小数部2桁になるように切り捨てして、文字列に変換
FloatToDec2String<public>(Number:float)<transacts>:string=
    NumberString:string = ToString(Number)
    var RetVal:string = ToString(Number)
    if:
        Num1:float = Number * 100  #(例)1.2301 ⇒ 123.01, -1.2301 ⇒ -123.01
        Num1Int:int = Int[Num1] #(例)123, -123
        
    then:
        FloatAfterInt:float = Num1Int * 1.0 / 100.0 #(例)1.23, -1.23
        if:
            DecimalPointIdx := "{FloatAfterInt}".Find['.'] #(例)1, 2
            NewString := "{FloatAfterInt}".Slice[0, DecimalPointIdx+3] #(例)"1.23", "-1.23"

        then:
            set RetVal = NewString
    RetVal