Добавлен
Мне нужно преобразовать real в integer так, чтобы каждый real имел свой integer (как у функции GetHandleId( ), только вместо handle должен быть real). Нативная функция R2I( ) может вернуть одно и то же значение для разных real'ов ( R2I( 0.01 ) == R2I( 0.02 ) ).

Попробовал умножать real на 10 000 000, так, например, GetRealId( 0.03125 ) == 312500, но так можно упереться в потолок 2147483647
function GetRealId takes real whichReal returns integer
	return ( whichReal * 10000000 )
endfunction

В мемхаке нашел следующую функцию, но хотелось бы, чтобы функция работала без return bug'a
раскрыть
//# +nosemanticerror
    function realToIndex takes real r returns integer
        loop
            return r
        endloop
        return 0
    endfunction

    function cleanInt takes integer i returns integer
        return i
    endfunction

    function mR2I takes real r returns integer
        return cleanInt( realToIndex( r ) )
    endfunction
Можно сократить до (вроде работает):
//# +nosemanticerror
    function R2IEx takes real r returns integer
        loop
            return r
        endloop
        return 0
    endfunction

Принятый ответ

Сделал следующим образом:
раскрыть
	function interface callback takes integer this returns nothing defaults nothing


    struct linkedList

        private static timer    period      = null
        private        real     curTimeout
        private        real     timeout
        private        thistype prev
        private        thistype next
        private        callback handlerFunc


		static constant method operator listPeriod takes nothing returns real
            return 0.01
        endmethod


        method destroy takes nothing returns nothing
            set this.prev.next = this.next
            set this.next.prev = this.prev

            if (thistype(0).next == thistype(0)) then
                call PauseTimer(this.period)
            endif

            call thistype.deallocate(this)
        endmethod


        private static method iterate takes nothing returns nothing
            local thistype this = thistype(0).next

            loop
                exitwhen (this == thistype(0))

                set this.curTimeout = this.curTimeout + thistype.listPeriod

                if (this.curTimeout >= this.timeout) then
                    set this.curTimeout = 0.0
                    call this.handlerFunc.evaluate(integer(this))
                endif

                set this = this.next
            endloop
        endmethod


        static method create takes real timeout, callback handlerFunc returns thistype
            local thistype this = thistype.allocate()

            set this.next        = thistype(0)
            set this.prev        = thistype(0).prev
            set this.next.prev   = this
            set this.prev.next   = this
            set this.timeout     = timeout
            set this.curTimeout  = 0.0
            set this.handlerFunc = handlerFunc

            if (thistype.period == null) then
                set thistype.period = CreateTimerEx()
            endif

            if (this.prev == thistype(0)) then
                call TimerStart(thistype.period, thistype.listPeriod, true, function thistype.iterate)
            endif

            return this
        endmethod


    endstruct
Будет ли это создавать большую нагрузку на игру из-за низкого периода таймера, несмотря на то, что таймер хоть и работает с низкой частотой, он ничего толком то и не делает, кроме арифметических вычислений?
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
30
6 лет назад
0
Fakov, А если число пятизначное?
0
32
6 лет назад
0
Clamp:
Fakov, А если число пятизначное?
какая разница если у него впереди есть ноль с точкой. если не требуется обратного конверта - то все ок. Интежер из R2S(0.05678) будет '5678'
Уверен, обратно конвертнуть интежер в исходный real тоже можно
0
30
6 лет назад
0
Fakov, такая, что максимальный размер массива 8192, что есть четырёхзначное число.
Fakov, 0.56792
А, или вот тебе вариант: есть числа 0.012 и 0.12, как быть?
0
32
6 лет назад
0
Clamp:
Fakov, такая, что максимальный размер массива 8192, что есть четырёхзначное число.
Fakov, 0.56792
А, или вот тебе вариант: есть числа 0.012 и 0.12, как быть?
Лол, как это 8192))))))) это мне щас нихерово так портит всю концепцию доты3
но челлендж понял, попробую найти пруф оф концепт попзжее
0
30
6 лет назад
0
Обычно в таких ситуациях используют какой-нибудь алгоритм хеширования значений, что, очевидно, сильно увеличивает нагрузку на систему.
0
21
6 лет назад
Отредактирован scopterectus
0
Идея со структурой мне показалось очень интересной, но увы, не работает.
раскрыть
	struct timeout
        private real     period
        private thistype prev
        private thistype next

        private static method inStock takes real period returns thistype
            local  thistype  this  =  thistype( 0 ).next
            loop
                exitwhen ( this == thistype( 0 ) ) or ( this.period == period )
                set  this  =  this.next
            endloop
            return this
        endmethod

        static method create takes real period returns thistype
            local thistype this = thistype.inStock( period )
            call BJDebugMsg( "inStock" + I2S( this ) )
            if ( this == thistype( 0 ) ) then
                set this             = thistype.allocate( )
                set this.next        = thistype( 0 )
                set this.prev        = thistype( 0 ).prev
                set this.next.prev   = this
                set this.prev.next   = this
                set this.period      = period
            endif
            return this
        endmethod
    endstruct
В методе inStock, если идёт сравнение 0,03125 и 0,03126, то игра считает, что это одинаковые числа.

Fakov, такая, что максимальный размер массива 8192, что есть четырёхзначное число.
Это неважно, мне не обязательно хранить в массиве, поэтому ограничения 8192 нет. Можно просто:
SaveHandle( hash, randomKey, R2I( real ), handle ), главное, чтобы R2I( ) возвращал уникальные значения для каждого real'a.
1
17
6 лет назад
1
ScopteRectuS, в программировании сравнивать действительные числа не принято, это в большинстве случаев дает неверный результат из-за потери точности и принципа хранения данных.
1
21
6 лет назад
1
Попробовал return bug, возвращает уникальные значения у real'ов, имеющих 31 символа после запятой, после 32 символа начинает возвращать 0:
function realToInteger takes real r returns integer
    loop
        return r
    endloop
    return 0
endfunction
    
    
function func_name takes nothing returns nothing
    call BJDebugMsg( I2S( realToInteger( 0.12345 ) ) )                             // return 1039979357
    call BJDebugMsg( I2S( realToInteger( 0.123456 ) ) )                            // return 1039980161
    call BJDebugMsg( I2S( realToInteger( 0.1234567 ) ) )                           // return 1039980256
    call BJDebugMsg( I2S( realToInteger( 0.12345678 ) ) )                          // return 1039980265
    call BJDebugMsg( I2S( realToInteger( 0.123456789 ) ) )                         // return 1039980266
    call BJDebugMsg( I2S( realToInteger( 0.1234567890 ) ) )                        // return ...
    call BJDebugMsg( I2S( realToInteger( 0.12345678901 ) ) )                       // return ...
    call BJDebugMsg( I2S( realToInteger( 0.123456789012 ) ) )                      // return ...
    call BJDebugMsg( I2S( realToInteger( 0.1234567890123 ) ) )                     // return ...
    call BJDebugMsg( I2S( realToInteger( 0.12345678901234 ) ) )                    // return ...
    call BJDebugMsg( I2S( realToInteger( 0.123456789012345 ) ) )                   // return ...
    call BJDebugMsg( I2S( realToInteger( 0.1234567890123456 ) ) )                  // return ...
    call BJDebugMsg( I2S( realToInteger( 0.12345678901234567 ) ) )                 // return ...
    call BJDebugMsg( I2S( realToInteger( 0.123456789012345678 ) ) )                // return ...
    call BJDebugMsg( I2S( realToInteger( 0.1234567890123456789 ) ) )               // return ...
    call BJDebugMsg( I2S( realToInteger( 0.12345678901234567890 ) ) )              // return ...
    call BJDebugMsg( I2S( realToInteger( 0.123456789012345678901 ) ) )             // return ...
    call BJDebugMsg( I2S( realToInteger( 0.1234567890123456789012 ) ) )            // return ...
    call BJDebugMsg( I2S( realToInteger( 0.12345678901234567890123 ) ) )           // return ...
    call BJDebugMsg( I2S( realToInteger( 0.123456789012345678901234 ) ) )          // return ...
    call BJDebugMsg( I2S( realToInteger( 0.1234567890123456789012345 ) ) )         // return ...
    call BJDebugMsg( I2S( realToInteger( 0.12345678901234567890123456 ) ) )        // return ...
    call BJDebugMsg( I2S( realToInteger( 0.123456789012345678901234567 ) ) )       // return ...
    call BJDebugMsg( I2S( realToInteger( 0.1234567890123456789012345678 ) ) )      // return -1065120231
    call BJDebugMsg( I2S( realToInteger( 0.12345678901234567890123456789 ) ) )     // return -1080887466
    call BJDebugMsg( I2S( realToInteger( 0.123456789012345678901234567890 ) ) )    // return  1067220501
    call BJDebugMsg( I2S( realToInteger( 0.1234567890123456789012345678901 ) ) )   // return -1108908349
    call BJDebugMsg( I2S( realToInteger( 0.12345678901234567890123456789012 ) ) )  // return  0
    call BJDebugMsg( I2S( realToInteger( 0.123456789012345678901234567890123 ) ) ) // return  0
ScopteRectuS, также, что удивительно, одинаковые числа, но имеющие разное кол-во введённых символов выдают разные числа:
    call BJDebugMsg( I2S( realToInteger( 0.12345678901234567890123456789 ) ) )     // return -1080887466
    call BJDebugMsg( I2S( realToInteger( 0.123456789012345678901234567890 ) ) )    // return  1067220501
0
30
6 лет назад
0
Потому что это адреса в памяти, они априори уникальны для каждого числа.
1
16
6 лет назад
1
realtoInt, очевидно, возвращает то, как записано число в памяти, только и всего. конечно же, там и дефолтная погрешность
1
28
6 лет назад
Отредактирован PT153
1
Попробовал return bug, возвращает уникальные значения у real'ов, имеющих 31 символа после запятой, после 32 символа начинает возвращать 0:
31 символ после запятой? JASS неадекватно обрабатывает числа с более 9-ти знаками после запятой, и даже в некоторых числах, у которых знаков после запятой меньше 9, совершает ошибки.
Вот статья.
также, что удивительно, одинаковые числа, но имеющие разное кол-во введённых символов выдают разные числа:
Причина этому дана выше.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.