
Should the API use decimal instead of long?
Darkhax opened this issue · 17 comments
It has been suggested several times (1, 2, 3) that the Tesla API should switch to a decimal system instead of Integer.
Benefits
- Easier to split power into multiple units. For example 0.166t sent to every face of the block.
- Much larger amounts of power can be dealt with. (Double is 1.7976931348623157E308 which is a lot!)
Disadvantages
- Much slower calculations for things like energy distribution, and addition / subtraction.
- Much less precise in calculations. Not a huge issue, but if not dealt with can cause strange situations.)
An alternative suggestion would be to add a new tier below Tesla called microTesla. The microTesla tier would allow for power to be split up into decimal values. For example 1.243 tesla would represent 1243 microTesla. 1 Tesla would still equal 1RF.
If you have any related suggestions please comment below. Voting for this poll will be handled by reactions. Thumbs up for yes, thumbs down for no. If you like the alternative suggestion, vote confetti.
The internal scale doesn't have to be immediately player-visible (I consider "mB" becoming the standard of liquid measure to be a mistake, it could have been left as a decimal number of Buckets).
As for BigInteger, that seems problematic, as memory use and processing time scales linearly with the number of digits, implying a "relatively low" maximum value before there's no RAM left. If you want big, instead look into how Hypercalc works. I still wouldn't recommend it for a Minecraft mod, though.
That's a good thing to factor in too: You wouldn't want it consuming ALL RAM allocated to Minecraft.
Hmm... Maby a kinda messy solution to this issue but perhaps you could have a second send/receive method that accepts doubles. Then the logic would work something like this.
You have the primary energy storage that is a long value and a secondary field that holds a double. Then if the handler receives say 1.5T the primary storage would take the 1 and the remaining .5 would go to the secondary storage. Now say the handler receives another 1.5T the same thing would happen but now the secondary storage has 1T which can be removed and injected into the primary storage.
p.s. This is a terrible idea and everyone should give it a thumbs down. half way through i was considering just canceling and keeping the idea to myself because it would be such a pain to implement. But i decided to post it anyway in case it gives someone else a better idea along the same lines.
Hmm... I guess considering all the extra zero's you have available using longs the idea of shifting the scale isn't terrible... But i also really like the idea of being directly compatible with the RF API.
And lets face it you made this API so we can make things BIGGER!!! not smaller.
Oh i may have a better solution. You could use the scaled system but also scale down the units so 1 tesla becomes 1 milli-Tesla and 1000 milli-Tesla= 1 Tesla.
If you do this you should also create a better format method that converts say a value like 134123 to something like 134.123T That makes it much more user (end user) friendly and gives you smaller units to work with behind the scenes.
@brandon3055 Did you see the alternative suggestion that was added to the original post? It describes exactly what you just said :p
Edit: I probably could have described it better though lol
Yea when i sayd "You could use the scaled system but" i was referring to what you suggested. Accept im suggesting you also scale down the units so 1 Tesla is still equal to 1 RF
Ok. But the BIGGEST issue with this idea is you would no longer be able to go all the way to 9 Quintilian Tesla meaning you would loos the direct compatibility with DE!
Yeah, that would be a bit of an issue. I forgot that there were people crazy enough to actually deal on the Q scale :p
Well im pretty sure at this point its just me... But you can be sure that now i have done it others will soon do the same lol.
I had a random thought once but it was to crazy for even me. I considered creating a custom EnergyStorage class that uses 2 longs. So it could theoretically store... Whats Long.MAX_VALUE * Long.MAX_VALUE?
Edit: I figured out the answer! It may have taken Big Int's to do the calculation...
85,070,591,730,234,615,847,396,907,784,232,501,249
Yeah, I have a few issues with that change as well. It would introduce mT which can be confused with MT. While I don't have a problem with TT/t mt/MT actually has potential for being confusing.
I hope it won't be confused, after all; people who play FTB and make intricate systems with machines should know the difference between milli and Mega.
What I suggested, but now better thought out:
- 1.000.000 : 1 = BASE
- BASE x 10^-6 RF = BASE x 10^-6 T (1 microTesla (μT))
- BASE x 10^-3 RF = BASE x 10^-3 T (1 milliTesla (mT))
- BASE x 10^1 RF = BASE x 10^1 T
- BASE x 10^3 RF = BASE x 10^3 T (1 kiloTesla (kT)
- BASE x 10^6 RF = BASE x 10^6 T (1 MegaTesla (MT))
Because that uses the SI prefixes, there won't be confusion between the long and short scale (short scale is used in US, long scale everywhere else) (for example: billion is milliard in long scale, and trillion is billion in long scale), and mostly everybody knows those prefixes.
Another benefit of using the SI prefixes (the way i described); you specify what the base is in RF, and all the other scales are applied too (down and up to whatever you want, but I think there is no need to go bigger or smaller)
@Dhvagra Interesting system, however I am somewhat confused by it. By making the base 1M RF you are creating a precision to 6 decimal places. This amount of precision isn't really needed. Another issue is the simple support for other RF mods. For example @brandon3055 is planning on adding support in Draconic Evolution (I think), so it would be very complicated for him to do such a drastic shift in power scales. This would also over complicate balancing for any mod that wants to support both RF and Tesla.
By making the base 1 million RF = 1 T, you can easily convert RF to T. It's RF/scale. So, you have 10.000 RF, but you want it in Tesla. 1 MRF = 1 T means for every million RF you get 1 Tesla.
That means 10.000/1.000.000 = 0,01 T. (or 1 centiTesla, because SI prefix)
Why not use BigInteger?
http://docs.oracle.com/javase/6/docs/api/java/math/BigInteger.html
- Much, much larger amounts of power can be dealt with. (BigInteger has theoretically no limit!)
- You don't have to deal with floating point errors like with double
- You can convert it to double, long and integer (if it's small enough of course)
- AFAIK you can do all the arithmetic things you can do with an Integer (correct me if I'm wrong)
Don't know of any performance impacts, though. I suspect it gets "worse" with bigger numbers, but I assume not much, or even notably much.