Item Search
     
BG-Wiki Search
Page 9 of 12 FirstFirst ... 7 8 9 10 11 ... LastLast
Results 161 to 180 of 231

Thread: Cast and Recast     submit to reddit submit to twitter

  1. #161
    Groinlonger
    Join Date
    Oct 2006
    Posts
    2,963
    BG Level
    7
    FFXI Server
    Fenrir

    Aero III example using Loq Earring

    99/100 = 0.989746093750000[round to zero] 0.990234375000000 [round to the nearest]
    0.989746093750000*25.25 = 24.9910888671875 => 24.9843750000000[round towards zero]
    or
    99/100 = 0.990234375000000 [round to the nearest]
    0.990234375000000 *25.25 =25.00341796875 => 25 [round to the nearest]

    So that result can be produced too if round to the nearest is used.

    Edit: Actually, it can't, it seems, because the result was 24 not 25, so perhaps round towards zero is the rounding method.

  2. #162
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Could also be discretization error in the case of Cures.
    Er, no, at least not in the sense that I think you're implying. EG: with 300 power, Cure IV cures 450 HP. With 400 power, Cure IV cures 520 HP. It scales linearly between those two points. Every 10 points of power increases the amount cured by 7 HP. So you'll see it increasing like: 450, 450, 451, 452, 452, 453, 454, 454, 455, 456, 457.

    Also, for the Curaga IV cases, you have come to an erroneous conclusion.
    You're correct, I forgot to round the third time.

    That also gives me an idea of how to rewrite the code....

  3. #163
    Groinlonger
    Join Date
    Oct 2006
    Posts
    2,963
    BG Level
    7
    FFXI Server
    Fenrir

    Er, no, at least not in the sense that I think you're implying. EG: with 300 power, Cure IV cures 450 HP. With 400 power, Cure IV cures 520 HP. It scales linearly between those two points. Every 10 points of power increases the amount cured by 7 HP. So you'll see it increasing like: 450, 450, 451, 452, 452, 453, 454, 454, 455, 456, 457.
    That is discretization in the sense that I am implying. The cure system on the wiki has many odd values for rates and such things. It's unlikely to be exact. The formulas are mostly accurate but in a sense a product of the discretization error created by the true system.

  4. #164
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    New code (RN stands for round-nearest):
    Spoiler: show

    Code:
    Public Function Float16MultRN(x As Double, y As Double)
    
    Let xF16 = GetFloat16RN(x)
    Let yF16 = GetFloat16RN(y)
    
    Float16MultRN = GetFloat16RN((xF16 * yF16))
    
    End Function
    Code:
    Public Function Float16AddRN(x As Double, y As Double)
    
    Let xF16 = GetFloat16RN(x)
    Let yF16 = GetFloat16RN(y)
    
    Float16AddRN = GetFloat16RN((xF16 + yF16))
    
    End Function
    Code:
    Public Function Float16SubRN(x As Double, y As Double)
    
    Let xF16 = GetFloat16RN(x)
    Let yF16 = GetFloat16RN(y)
    
    Float16SubRN = GetFloat16RN((xF16 - yF16))
    
    End Function
    Code:
    Public Function GetFloat16RN(x As Double)
    
    Let intBits = Int(Log(x)) + 1
    Let scaleBits = 15 - intBits
    If scaleBits < 0 Then
        scaleBits = 0
    End If
        
    Let scaleDbl = x * 2 ^ scaleBits
    Let scaleLng = CLng(scaleDbl)
    
    Let f16Lng = GetRoundFloat16((scaleLng))
    Let f16Dbl = CDbl(f16Lng) / 2 ^ scaleBits
    
    GetFloat16RN = f16Dbl
    
    End Function
    Code:
    Public Function GetRoundFloat16(x As Long)
    
    Let exponent = 0
    If Int(((Log(x) / Log(2)) + 1) - 11) > 0 Then
        exponent = Int(((Log(x) / Log(2)) + 1.00000000000001) - 11)
    End If
        
    Let lowerBits = Int(2047 / 2 ^ (11 - exponent))
    Let andLowerBits = BITAND(x, (lowerBits))
    
    Let roundBit = 0
    If andLowerBits > (lowerBits / 2) Then
        roundBit = 1
    End If
    
    Let mainBits = 2047 * 2 ^ exponent
    Let andMainBits = BITAND(x, (mainBits)) + roundBit * (lowerBits + 1)
    
    GetRoundFloat16 = andMainBits
    
    End Function
    Code:
    Public Function BITAND(x As Long, y As Long)
    BITAND = x And y
    End Function


    7% ~~

    From half_table.txt:
    0.0700073242187500

    Calculated in Excel [GetFloat16RN(7%)]:
    0.0700073242187500

    So doing fine there.

    Function call from Excel:

    Float16MultRN(baseRecast, 1-haste%) [also tried: Float16SubRN(baseRecast, Float16MultRE(baseRecast, haste%))]

    Curaga IV with 7% haste: 10

    However, as you point out, Aero III with 1%: 25.

    With Round-nearest, Curaga IV is correct, but Aero III is wrong; with Round-zero Aero III is correct, but Curaga IV is wrong. I also tried Round-even, but it has the same problem; Aero III is correct, but Curaga IV is wrong.

    Will do some double-checking later to make sure I didn't mess anything up with copy/paste on some of the variants.

  5. #165
    Groinlonger
    Join Date
    Oct 2006
    Posts
    2,963
    BG Level
    7
    FFXI Server
    Fenrir

    Well, I think it's safe to say that the rounding system is round down. I can't imagine getting the fast cast results we do unless the system as float((100-f/2)/100) where everything is integer math until the quotient is taken. If you assume that to be true, then Aero III results can only be produced if round down is the default rounding method.

    Curaga IV results don't necessarily rule out n/1000 results. It just depends on how you implement it, and values used could still be values other than nominal. I'm hoping it's not though, that would result in a lot of wasted effort, but it would be a good idea to examine other approaches because it's very possible that float16 discretization was causing people to conclude an n/1024 system.

  6. #166
    Groinlonger
    Join Date
    Oct 2006
    Posts
    2,963
    BG Level
    7
    FFXI Server
    Fenrir

    Um, also, why are you creating functions to multiply/add/etc. float16 numbers? You can achieve those results with use of a single rounding function.

    For Curaga IV~

    GetFloat16RN(25.25*GetFloat16RN(99/100))

  7. #167
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Aero III results can only be produced if round down is the default rounding method.
    Well, either that or Round-odd.

    Curaga IV results don't necessarily rule out n/1000 results.
    Curaga IV results can -only- be produced with Round-nearest or Round-even, diametrically opposed to the Aero III results.

    Edit: ehh.. scratch the odd/even.. that should really only apply when at exactly 0.5 between two points, and that doesn't seem to be the case with these; need to redo the code there

    I've tried a number of variations on operation order (subtract haste/fc from 1 and multiply by recast; multiply haste/fc by recast and subtract from recast, etc), and have not been able to get a different result for either of the above two spells, for any given rounding method.

    it would be a good idea to examine other approaches because it's very possible that float16 discretization was causing people to conclude an n/1024 system.
    Indeed.

  8. #168
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Actually, there's one other way we could end up with these results: Add 0.01 to the final value before truncating.

    Curaga IV @7%: 9.9994 + 0.01 = 10.0094 >> 10.000
    Aero III @1%: 24.984 + 0.01 = 24.994 >> 24.984

    (note: don't have my spreadsheet here, so the above won't be precise to float16; the final >> is after the forced round down, not the int truncation)

    Basically, it's possible they may have done that to smooth out some rounding issues, the way I had to when calculating the exponent in the VBA code. Log(32768)/Log(2) = 15, however Int(Log(32768)/Log(2)) returned 14. I added an extra 0.00000000000001 to make sure I got the correct value despite the data type's imprecision.

    If they ever had reason to do the same thing (and it's not that far fetched), that would explain the discrepancy. I haven't done any comparisons with known results, though, so this is just guesswork right now.



    As for the source resolution of haste, I think we can test that using a Hasty Pinion or Arbuda Grip (1% haste). Compare its results with the Loquacious earring. If the Pinion is 10/1000, it should be identical to Loquacious. If Pinion is 10/1024, it should give 25 seconds for Aero III. If Pinion is 11/1024 you'll need to find another spell to compare with to distinguish between that and 10/1000 (again, don't have spreadsheet here right now, so can't pick one out).

    No Hasty Pinions for sale on Fenrir, however I think I remember getting an Arbuda Grip not too long ago. I should still have it in storage.

  9. #169
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Did another rewrite of the code. Cleaned up a bit. Round nearest now uses Round-even for the 50% point. Tested remainder using Round-zero.

    First test, equivalency of haste and fast cast.

    Arbuda grip (1% haste)
    Aero III: 25 seconds

    Conclusion: Haste is -not- 1:1 equivalent to Fast Cast recast. As such, the discrepancy of 7% haste on Curaga IV is not in conflict with the rounding determined by Aero III with 1% FC.

    This will probably return us to using /1024 for haste. Can also ignore my little divergence in the post above.

  10. #170
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Am unable to think of any other model for haste, since we can already be sure it's not /100 or /1000, so assuming /1024 as the units for now. If you have any other ideas, let me know.

    Considered a few general orders of operation:
    =Float16MultRZ(recast, (1024-haste)/1024)
    =Float16SubRZ(recast, Float16MultRZ(recast, haste/1024))
    =Float16DivRZ(Float16MultRZ(recast, (1024-haste)), 1024)

    At high haste values and high recast spells, there is a difference in the results.

    For Tornado at 200/1024 haste, recast should be 33 seconds using the first calculation order, and 34 seconds using the second calculation order.

    Haste spell + W.Turban should give 200/1024

    Observed recast: 33 seconds

    So the second calculation order is discarded. Checking against the third calculation order... The third calculation order does not appear to ever diverge from the results of the first calculation order, so can be considered equivalent.

    So, we multiply by 1-haste, rather than subtracting the product from the original value.


    Revisiting haste>fc vs fc>haste:

    230/1024 haste (spell + Turban + Witful) + 3% fast cast (Loq + Prolix + Witful)

    Aero IV: 25 if haste first, 24 if fc first
    ~ observed: 25
    Thunder IV: 28 if haste first, 27 if fc first
    ~ observed: 28


    Current VBA code:

    Spoiler: show
    Code:
    Public Function BITXOR(x As Long, y As Long)
    BITXOR = x Xor y
    End Function
    
    Public Function BITAND(x As Long, y As Long)
    BITAND = x And y
    End Function
    
    Public Function BITOR(x As Long, y As Long)
    BITOR = x Or y
    End Function
    
    Public Function GetRoundFloat16(x As Long)
    
    Let exponent = 0
    If Int(((Log(x) / Log(2)) + 1) - 11) > 0 Then
        exponent = Int(((Log(x) / Log(2)) + 1.00000000000001) - 11)
    End If
    
    Let mainBits = 2047 * 2 ^ exponent
    Let andMainBits = BITAND(x, (mainBits)) + roundBit * (lowerBits + 1)
    
    Let lowerBits = Int(2047 / 2 ^ (11 - exponent))
    Let andLowerBits = BITAND(x, (lowerBits))
    
    Let roundBit = 0
    
    If andLowerBits > 0 Then
        Let midBit = lowerBits - (lowerBits + 1) / 2
        
        If midBit = lowerBits Then
            Let lowestBit = BITAND((mainBits), midBit * 2)
            If lowestBit > 0 Then
                roundBit = 1
            End If
        Else
            If andLowerBits > midBit Then
                roundBit = 1
            End If
        End If
    End If
    
    andMainBits = andMainBits + roundBit * (lowerBits + 1)
    
    GetRoundFloat16 = andMainBits
    
    End Function
    
    Public Function GetFloat16RN(x As Double)
    
    Let intBits = Int(Log(x)) + 1
    Let scaleBits = 15 - intBits
    If scaleBits < 0 Then
        scaleBits = 0
    End If
        
    Let scaleDbl = x * 2 ^ scaleBits
    Let scaleLng = CLng(scaleDbl)
    
    Let f16Lng = GetRoundFloat16((scaleLng))
    Let f16Dbl = CDbl(f16Lng) / 2 ^ scaleBits
    
    GetFloat16RN = f16Dbl
    
    End Function
    
    Public Function Float16AddRN(x As Double, y As Double)
    
    Let xF16 = GetFloat16RN(x)
    Let yF16 = GetFloat16RN(y)
    
    Float16AddRN = GetFloat16RN((xF16 + yF16))
    
    End Function
    
    Public Function Float16SubRN(x As Double, y As Double)
    
    Let xF16 = GetFloat16RN(x)
    Let yF16 = GetFloat16RN(y)
    
    Float16SubRN = GetFloat16RN((xF16 - yF16))
    
    End Function
    
    Public Function Float16MultRN(x As Double, y As Double)
    
    Let xF16 = GetFloat16RN(x)
    Let yF16 = GetFloat16RN(y)
    
    Float16MultRN = GetFloat16RN((xF16 * yF16))
    
    End Function
    
    Public Function Float16DivRN(x As Double, y As Double)
    
    Let xF16 = GetFloat16RN(x)
    Let yF16 = GetFloat16RN(y)
    
    Float16DivRN = GetFloat16RN((xF16 / yF16))
    
    End Function
    
    Public Function GetRoundZeroFloat16(x As Long)
    
    Let exponent = 0
    If Int(((Log(x) / Log(2)) + 1) - 11) > 0 Then
        exponent = Int(((Log(x) / Log(2)) + 1.00000000000001) - 11)
    End If
    
    Let mainBits = 2047 * 2 ^ exponent
    Let andMainBits = BITAND(x, (mainBits))
    
    Let roundBit = 0
    
    Let lowerBits = Int(2047 / 2 ^ (11 - exponent))
    Let andLowerBits = BITAND(x, (lowerBits))
    
    If x < 0 Then
        roundBit = 1
        andMainBits = Math.Abs(andMainBits) * -1
    End If
    
    andMainBits = andMainBits + roundBit * (lowerBits + 1)
    
    GetRoundZeroFloat16 = andMainBits
    
    End Function
    
    Public Function GetFloat16RZ(x As Double)
    
    Let intBits = Int(Log(x)) + 1
    Let scaleBits = 15 - intBits
    If scaleBits < 0 Then
        scaleBits = 0
    End If
        
    Let scaleDbl = x * 2 ^ scaleBits
    Let scaleLng = CLng(scaleDbl)
    
    Let f16Lng = GetRoundZeroFloat16((scaleLng))
    Let f16Dbl = CDbl(f16Lng) / 2 ^ scaleBits
    
    GetFloat16RZ = f16Dbl
    
    End Function
    
    
    Public Function Float16AddRZ(x As Double, y As Double)
    
    Let xF16 = GetFloat16RZ(x)
    Let yF16 = GetFloat16RZ(y)
    
    Float16AddRZ = GetFloat16RZ((xF16 + yF16))
    
    End Function
    
    Public Function Float16SubRZ(x As Double, y As Double)
    
    Let xF16 = GetFloat16RZ(x)
    Let yF16 = GetFloat16RZ(y)
    
    Float16SubRZ = GetFloat16RZ((xF16 - yF16))
    
    End Function
    
    Public Function Float16MultRZ(x As Double, y As Double)
    
    Let xF16 = GetFloat16RZ(x)
    Let yF16 = GetFloat16RZ(y)
    
    Float16MultRZ = GetFloat16RZ((xF16 * yF16))
    
    End Function
    
    Public Function Float16DivRZ(x As Double, y As Double)
    
    Let xF16 = GetFloat16RZ(x)
    Let yF16 = GetFloat16RZ(y)
    
    Float16DivRZ = GetFloat16RZ((xF16 / yF16))
    
    End Function

  11. #171
    Groinlonger
    Join Date
    Oct 2006
    Posts
    2,963
    BG Level
    7
    FFXI Server
    Fenrir

    I implemented my own VBA function for rounding down a number to float16, which is as follows.

    Code:
    Function float16(x As Double)
    
    Dim c As Integer
    Dim n As Integer
    
    c = (Log(x) / Log(2) + 2 ^ (-15))
    
    s = 2 ^ (c - 10)
    n = Int((x - 2 ^ c) / (s))
    
    float16 = (2 ^ c + (s * n))
    
    End Function
    Implementing this in the six ways (which turns out to only be three ways, because some are identical) yielded the following data.

    Code:
    f	h	Spell		Observed	A	B	C	D
    2	231	Stoneskin	23		23	22	22	22
    2	231	Reraise		46		46	45	45	45
    8	150	Freeze		34		34	33	33	34
    22	150	Blizzard II	15		15	14	14	14
    30	81	Blizzard	8		9	8	8	8
    So basically, none of them worked. They're truncating too hard. It could be the rounding mode, round towards zero, is not the one being implemented. The Loq earring test makes it seem like it would, but there is a slight problem with it. The true answer (.99) is very close to the middle of two discretized values in float16. It requires 7 additional precision bits to express the exact answer. I don't actually know what happens when a computer multiplies two float16 numbers. I consulted some literature and other resources, but honestly, I don't know enough about the exact routine it would take in executing that computation.

    There's a good possibility still that Haste is in some n/1000 system and the like. Assuming that the amount of haste is equal to the nominal value, or some multiple of it (x10) and then doing a test that rejects it still doesn't rule it out. If there are arbitrary values placed on gear, such as 11/1024 or 10/1024, there's no reason there couldn't be 10/1000 or 11/1000.

    Either way, seems like this problem is just becoming more complicated and troublesome.

  12. #172
    Groinlonger
    Join Date
    Oct 2006
    Posts
    2,963
    BG Level
    7
    FFXI Server
    Fenrir

    Tried reimplementing with F = 1-[f]/100 type model and round to the nearest.

    Code:
    f	h	Spell		Observed	A	B	C	D
    2	231	Stoneskin	23		23	23	23	23
    2	231	Reraise		46		46	46	46	46
    8	150	Freeze		34		34	34	34	34
    22	150	Blizzard II	15		15	15	15	15
    30	81	Blizzard	8		9	9	9	9
    Failure again.

  13. #173
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    Redone with haste as /1024 again, newest code
    Haste >> FC

    Float16 (1) = ((recast * haste) * fc)
    Float16 (2) = recast * (haste * fc)

    Code:
    Spell         Haste     FC    Observed     Float16 (1)   Float16 (2)
    Cure III        162      1           4              4             4
    Cura            162      1          25             24            24
    Protectra IV    162      1          14             14            14
    Protectra III   172      1          13             13            13
    Stoneskin       231      1          23             22            22
    Reraise         231      1          46             45            45
    Freeze          150      4          34             33            34
    Blizzard II     150     11          15             15            15
    Blizzard         81     15           8              8             8
    Newest code fixed Cure III; is now the proper 4 seconds instead of 5.
    If haste and fast cast are multiplied together before applying that to the base recast, that fixes Freeze; that shows up as the correct 34 seconds.

    That still leaves us with Cura, Stoneskin and Reraise as being incorrect.

    If it used round-nearest instead of round-zero, all three of those would yield the correct value. However doing so would cause Cure III and Protectra IV to become incorrect again.


    Another Haste vs Fast Cast comparison. Given the potential uncertainty of 1% items, rechecking at 2%.

    Fast Cast 1: Loq + Prolix, 2%
    Fast Cast 2: Orison Locket (5% fast cast, should be 2% recast)
    Haste: Blessed Pumps, 2%

    Observed:
    FC1: 49
    FC2: 49
    Haste: 49

    Well, this is interesting.

    Expected value of 2% with round-zero: 48
    Expected value of 2% with round-nearest: 49
    Expected value of 20/1024: 49


    I was expecting either for the haste to return 49 and the FC to return 48 (if haste is /1024), or for both to return 48 (if haste is /1000). Instead both return 49. This is directly contradictory to the Loq/Aero III test in terms of rounding, for the fast cast.

    Looking at it, I would get the correct answer by multiplying by 98, then dividing by 100, rather than multiplying by 0.98. Reworking...

    Ok, Cura III with 4% fast cast recast (Loq+Prolix+Orison Locket) should give 48 if it uses the *96/100 sequence, or 47 if it uses the *0.96 multiplier.

    Observed: 48

    Ok, so changing to using that form of calculation. Looking at the samples again

    (1a) = ((recast * haste) * fc)
    (2a) = recast * (haste * fc)
    (3a) = recast * (haste * fc), haste = /1000

    Code:
    Spell         Haste     FC    Observed   (1a)   (2a)   (3a) 
    Cure III        162      1           4      5      4      4 
    Cura            162      1          25     24     24     24 
    Protectra IV    162      1          14     14     14     14 
    Protectra III   172      1          13     13     13     13 
    Stoneskin       231      1          23     22     22     22 
    Reraise         231      1          46     45     45     45 
    Freeze          150      4          34     33     34     33 
    Blizzard II     150     11          15     15     15     15 
    Blizzard         81     15           8      8      8      8

    Cure III and Freeze are both incorrect if you do ((recast * haste) * fc), but both correct if you do (recast * (haste * fc)). Cura, Stoneskin and Reraise are all still incorrect.

    Using the same parameters, but changing to /1000 leaves the results mostly the same, but Freeze goes back to incorrect. This assumes things like 231/1024 haste is just a flat 230/1000, which isn't necessarily valid, but sufficient for a quick check.

  14. #174
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    1) Fast cast recast is /100

    2) Operation order is (recast * n) / N, not recast * (n / N).

    Evidence:

    Cura III has 50 second base recast. 2% fcr gave a 49 second recast, and 4% fcr gave a 48 second recast.

    If the 2%/98% or 4%/96% was converted to float first (assuming float16), there is no set of consistant rounding conditions (except round-up, which is incredibly unlikely for any real implementation) that will give a result better than 48.9688 (for the 2% case), since the closest float16 value to that is

    2%:
    0.0199890136718750
    0.0200042724609375

    98%:
    0.979980468750000
    0.980468750000000

    Round-nearest and round-zero will both end up with 0.979980468750000, regardless of which 2% value is chosen (0.0199 for round-zero, 0.0200 for round-nearest). Since a 49 second recast requires exactly 0.98 (or higher) as a multiplier, the float16 value will always end up less than 49 seconds.

    However multiplying as integers doesn't have this problem. 50 * 98 = 4900, which is evenly divisible by 100 to result in our 49 second recast.




    Haste as /1024 vs /1000:

    Using 3%-4% haste to avoid anomalies with either 1% or 5%+ values. Using (recast * n) / N based on conclusion #2.

    Cura III
    41/1024 gives a 47 second recast
    40/1024 gives a 48 second recast
    40/1000 gives a 48 second recast

    Observed: 48
    4% haste is not 41/1024

    Flood:
    40/1024 gives a 42 second recast
    40/1000 gives a 41 second recast

    Observed: 42

    40/1024 = 80/2048, and 70-81/2048 all give 42 seconds for Flood.



    Thundaga II at 78/2048 is 25, at 80/2048 is 24.

    Observed: 24

    Must be at least 79/2048

    Thundaga III with Headlong Belt (3% haste)

    If 60/2048 (0.029296875), 33 seconds; if 61/2048 (0.02978515625), 32 seconds; if 30/1000 (0.0299987792968750 - 0.0300140380859375), 32 seconds

    1 - 0.029296875 (60/2048) = 0.970703125
    1 - 0.02978515625 (61/2048) = 0.97021484375
    1 - 0.0299987792968750 => 0.97000122071 >> 0.969726562500000 or 0.970214843750000
    1 - 0.0300140380859375 => 0.96998596191 >> 0.969726562500000 or 0.970214843750000

    97%~
    0.969726562500000 * 34 = 32.971
    0.970214843750000 * 34 = 32.987
    0.970703125000000 * 34 = 33.004

    Observed: 33 seconds

    So must be 60/2048 or less, and /1000 does not allow for a correct result.


    Burst:

    If 60/2048, 41 seconds; if 59/2048, 42 seconds.

    Observed: 41

    So does not appear to be undervalued in /2048 units.


    So everything seems to be pointing to haste being in units of /1024.


    Aside:

    With 4% haste:
    Klimaform at 79/2048 is 172, 80/2048 is 173.

    Observed: 2:52 == 172

    However calculating 52+128 as base cast time (with extra trickery used on the 128 half), and doing the math separately for each to avoid overflow, gives a total of 172.9688 >> 172. I came across this earlier as well. Can pretty much say that Klimaform cannot be used as a test spell, since it seems to be calculated in two separate phases.


    Going back to working on combining haste and fast cast...

  15. #175
    Groinlonger
    Join Date
    Oct 2006
    Posts
    2,963
    BG Level
    7
    FFXI Server
    Fenrir

    Evidence:

    Cura III has 50 second base recast. 2% fcr gave a 49 second recast, and 4% fcr gave a 48 second recast.

    If the 2%/98% or 4%/96% was converted to float first (assuming float16), there is no set of consistant rounding conditions (except round-up, which is incredibly unlikely for any real implementation) that will give a result better than 48.9688 (for the 2% case), since the closest float16 value to that is

    2%:
    0.0199890136718750
    0.0200042724609375

    98%:
    0.979980468750000
    0.980468750000000

    Round-nearest and round-zero will both end up with 0.979980468750000, regardless of which 2% value is chosen (0.0199 for round-zero, 0.0200 for round-nearest). Since a 49 second recast requires exactly 0.98 (or higher) as a multiplier, the float16 value will always end up less than 49 seconds.

    However multiplying as integers doesn't have this problem. 50 * 98 = 4900, which is evenly divisible by 100 to result in our 49 second recast.
    This doesn't really work. You've forgotten again that the product of the two numbers needs to be rounded, you can't truncate arbitrarily.

    0.979980468750000*50 = 48.9990234375

    The two discretized values near that number are

    48.9687500000000
    49

    49 is much closer, and would be the result if round to the nearest was implemented.

    I'm not sure what to make of your haste conclusions. Haven't had enough time to review it.

  16. #176
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    This doesn't really work. You've forgotten again that the product of the two numbers needs to be rounded, you can't truncate arbitrarily.
    Bah, sort of. The basic conclusion is true if we accept the earlier conclusion of round-zero. I checked round-nearest as a secondary factor after doing the initial writeup, but didn't carry it all the way through.

    In that case the conclusion is either:
    1) Round-nearest, not round-zero
    2) (recast * n)/N, not recast * (n/N)

  17. #177
    Groinlonger
    Join Date
    Oct 2006
    Posts
    2,963
    BG Level
    7
    FFXI Server
    Fenrir

    I don't think round towards zero is true. Most of the times I've implemented it, round towards the nearest produced the best results. I think what may be going wrong is the way we're rounding. I've only been able to read a little bit about the actual process a computer will used to multiple two floats, but it seems like the "right in the middle" case will arise much more often than in the way we implement it. Basically, in cases where the exact result is close to halfway between two discretized float 16 values, a 16 bit computer thinks it is exactly halfway, and the rounding is a bit unpredictable. I'm not sure though, would require more reading, dunno if I'll put the effort into it.

  18. #178
    Groinlonger
    Join Date
    Oct 2006
    Posts
    2,963
    BG Level
    7
    FFXI Server
    Fenrir

    Here's my implementation of round towards the nearest. The results are what I would expect following IEEE 754 standards for round to the nearest (choosing 0 as the LSB in the case of being midway.)

    Code:
    Function float16(x As Double)
    
    Dim c As Integer
    Dim n As Integer
    Dim lower As Double
    Dim upper As Double
    Dim Odd As Integer
    
    c = (Log(x) / Log(2) + 2 ^ (-15))
    
    s = 2 ^ (c - 10)
    n = Int((x - 2 ^ c) / (s))
    
    lower = (2 ^ c + (s * n))
    upper = (lower + s)
    
    If (x - upper) = (s / 2) Then
        Odd = (n Mod 2)
        If Odd = 1 Then
            float16 = upper
        Else
            float16 = lower
        End If
    ElseIf (x - upper) < (x - lower) Then
        float16 = upper
    Else
        float16 = lower
    End If
    
    End Function
    I need a better version of Excel. The pirated one I have is breaking all the damn time to point where I just don't even feel like opening it.

  19. #179
    Groinlonger
    Join Date
    Oct 2006
    Posts
    2,963
    BG Level
    7
    FFXI Server
    Fenrir

    Hmm, there may be a bug in this.

    =float16(1.5+0) returns more than 1.5. I'll have to debug it, then retest some shit.

  20. #180
    Chram
    Join Date
    Sep 2007
    Posts
    2,526
    BG Level
    7
    FFXI Server
    Fenrir

    I found a bug in my implementation. Fixed it, and doing some more testing, though other things going on at the moment, so a bit slow.

Page 9 of 12 FirstFirst ... 7 8 9 10 11 ... LastLast