Добавлен  scopterectus 
                            
                            
                            
                            
                            
                            
                        
                        
                    Мне нужно преобразовать 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Будет ли это создавать большую нагрузку на игру из-за низкого периода таймера, несмотря на то, что таймер хоть и работает с низкой частотой, он ничего толком то и не делает, кроме арифметических вычислений?
    
        
            
                `
            
            
                
        
    
    ОЖИДАНИЕ РЕКЛАМЫ...
            
                    
                        Чтобы оставить комментарий, пожалуйста, войдите на сайт.
                    
                
             
                        
                        
                    
 WC3
                                WC3
                            



 
                    
                
Ред. scopterectus
Я бы сказал, что мною движет желание это сделать больше, чем оптимизация кода.
Вариант со StringHash(R2S(r)) здесь будет наиболее уместным, однако помни, что строки никуда из памяти не деваются, и остаются висеть в оперативе.
call BJDebugMsg( I2S( StringHash( R2S( 0.03126 ) ) ) ) == -1331723389
Ред. PT153
В математике R не ограничено, но наш мир ограничен, потому число действительных чисел ограничено в программировании. Каждому целому числу сопоставлено число с плавающей точкой.
Не используй R2S, это R2SW с точностью 3. Лучше используй R2SW с точностью -1.
В целом Clamp, говорит верно, такие потребности не должны возникать в логике программы, поскольку типы с плавающей запятой ненадежны, они с потерями.
Если нужно совсем прям совсем, можно использовать vJass/ZINC/Wurst и объявить структуру (в случае Wurst - класс) который будет содержать в поле данные типа real. Что-то вроде
Если бы мне нужно было бы хранить что-то в массиве данных с привязкой к числу 0.5683, то я бы конвертнул это число в строку, через конкат нашел бы и убрал бы "0." а оставшееся значение конвертнул бы в int и под этим значением записал бы ячейку массива.