Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[Func] autoByteFormat - convert bytes to byte(s)/KB/MB/GB/TB


  • Please log in to reply
51 replies to this topic
animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008

One more, semantics. Is it -1 byte or -1 bytes?

-1 byte sounds more natural to me.

K, thanks. Just finishing up some final touches, testing, you know... Hopefully, I can get it done within the hour or so.
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008
I just realized that my solution for how to allow both binary and decimal size inputs might be weird.

For example,

autoByteFormat(.9766 "KB", "bytes 1")
This presumes that the size is in (decimal) kilobytes.


To specify binary kilobytes, either of these work.

autoByteFormat(.9766 "KiB", "bytes 1")
or
autoByteFormat(.9766 "KBi", "bytes 1")

The latter is to easily allow values that are stored using KB (KiB is now an option) to still be marked as binary.

ex
size := ".9766 KB"
autoByteFormat(size "i", "bytes 1")

The "i" is the same "i" that appears in, for example, "KiB". I could easily switich it to "b" (for binary).

size := ".9766 KB"
autoByteFormat(size "b", "bytes 1")

As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
The "i" seems somehow counterintuitive, IMHO, when used standalone. However, if more people find it useful, you may allow both "b" and "i", just for the sake of logical intuition.

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008

The "i" seems somehow counterintuitive, IMHO, when used standalone. However, if more people find it useful, you may allow both "b" and "i", just for the sake of logical intuition.

Oh yeah, I could :p, good point. I'll do that. It won't cause any downside, thanks.
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008
Just wanted to give a quick update and a quick sorry that it's not up yet - yal can wait :p - it's worth the wait.

I've added a TON of stuff - so much that I'm writing a webpage for the function. It will be formatted like any other AHK page (same scheme and all), and will be posted on my AutoHotkey.net account. Instead of posting all the options in my first post, I'm going to post a link to the page. Additionally, I'm going to include the page in the zip (including the css sheets). This will allow offline viewing of the page. The webpage (along with several example scripts) will be in the "Func examples" folder. This will make it easy to find the page during offline viewing, as well as not cludder up your library folder.
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007

Just wanted to give a quick update and a quick sorry that it's not up yet - yal can wait :p - it's worth the wait.

I've added a TON of stuff - so much that I'm writing a webpage for the function. It will be formatted like any other AHK page (same scheme and all), and will be posted on my AutoHotkey.net account. Instead of posting all the options in my first post, I'm going to post a link to the page. Additionally, I'm going to include the page in the zip (including the css sheets). This will allow offline viewing of the page. The webpage (along with several example scripts) will be in the "Func examples" folder. This will make it easy to find the page during offline viewing, as well as not cludder up your library folder.


Sounds great. I'll be waiting for it!

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008
I have officially gone off the deep end. I'm right now adding the ability to parse the inputted size and set the settings apppropriately. You can, of course, override these defaults by specifing the applicable option. Parsing the input for the settings will work best if the input is properly formatted - the return from autoByteFormat will always be properly formatted. The function will still work for poorly formatted input, but parsing the input may be limited.


For example, if the input was "123,456.000 000e-1kB", this would use the following defaults.

1) The thousands delimiter would be a comma
2) The rounding for decimal places would be to 6 digts
3) A single space would be used to separate the decimal digits, and every three digits would be separated.
4) The return would be in scientific notation
5) There would be no separator between the value and unit (the default is a single space)


This will allow an easy way to retain the same formatting when converting between sizes, with the option of changing the formatting. Also, without it, there would be no way to retain the same formatting (without specifing all applicable options). I already added a similar support for the units, with an easy way to overload it. There will be an option that will disable this "parsing" (maybe -parse, haven't thought what to call it) - taking suggestions. To disable parsing, the "-parse" would have to be the first option. Even if you stored a "settings list" to a variable, and passed it (to easily use one of many different "profiles"), you can always easily specify the "-parse" as the first option. Additionally, you could optionally specify a number after the word parse - this would only disable specific settings. Each setting would have a "setting number", and you would specify the "setting number" to disable that setting. If it gets to more than 9 settings, letters would be used: "A" (for 10), "B" (for 11), etc. (case-insensitive) - this would allow up to 36 options to be handled by the "-parse" option.

settingsList = "option1 option2 option3"

;note the need for a space after "-parse31", to separate this option from the others.
;All settings, except the 1st and 3rd, would be parsed and set.  The 1st and 3rd would use the default value (and any others that couldn't be known from parsing).
autoByteFormatting(size, "-parse31 " settingsList)


If the value used for a setting cannot be determined, the default is used. Of course, you could override this default by specifing the applicable option.

For example, "123 KB" could not set

1) The thousands separator - uses default (none)
2) The rounding for the decimal places - uses default (2)
3) The separator for the decimal places, or the count - uses default (none, every 3rd digit)
4) The return would be in decimal notation (the default)

can set
5) There would be a single space between the value and the unit.


Looking for feedback on this idea.
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
If the letter "p" wouldn't clash with other options, it would be good to allow usage of "-p31" instead of/besides "-parse31" (as per your above example), to shorten the code line (since there's people around that care for looks). ;)

Bit of an off-topic, apologies: do you (or anyone else) know of a fast and neat way of recognizing the bytesize of a given variable? I.e. when the variable is 253 (dec), recognize it as BYTE (UChar), while if the variable is 565130498 (dec), recognize it as DWORD (UInt).

I'm trying to build a (probably useless) function and already got a way to do this, but was just wondering if there's a better way.


tonne
  • Members
  • 1654 posts
  • Last active: May 06 2014 06:22 PM
  • Joined: 06 Jun 2006
Dont know if this is neat ;-)
InputBox,Number,Size of number,Number
bits := log(Number)/log(2)
MsgBox % bits . " bits"
MsgBox % bits < 8 ? "byte" : bits < 16 ? "dword" : "qword"


animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008

If the letter "p" wouldn't clash with other options, it would be good to allow usage of "-p31" instead of/besides "-parse31" (as per your above example), to shorten the code line (since there's people around that care for looks). ;)<

Good point, thanks. I'll add support for "shorter names" as well as longer names - should keep everyone happy. Additionally, I'm going to release the function as a beta - hopefully the "webpage" can be finished today, so I can release it. At that time, I'll want feedback on anything that can be done to improve the function. I tried to think of every scenario that I could, and add support for it, but there might be something I overlooked, or something that is there, but isn't the most intuitive way. I'll be relaying on yal for feedback.

Do you (or anyone else) know of a fast and neat way of recognizing the bytesize of a given variable? I.e. when the variable is 253 (dec), recognize it as BYTE (UChar), while if the variable is 565130498 (dec), recognize it as DWORD (UInt).

I'm trying to build a (probably useless) function and already got a way to do this, but was just wondering if there's a better way.

A bunch of ifs - that's what comes to mind. You would have to decide how to handle the overlapping values. ex. 5 is a uint, int, uchar, char, etc.

You can check the DllCall function for the bounds. You might want to use hex values in the if branches, because it will make more sense when reading the code.

ex. a char is between -128 (-0x80) to 127 (0x7F), a short is between -32768 (-0x8000) to 32767 (0x7FFF), etc. The hex values make it very easy and clear what the code does, and which value you are specifing.
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008

Dont know if this is neat ;-)

InputBox,Number,Size of number,Number
bits := log(Number)/log(2)
MsgBox % bits . " bits"
MsgBox % bits < 8 ? "byte" : bits < 16 ? "dword" : "qword"

Neat idea - never even thought of doing that. One note, negative values and signed values would need adjusting.
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
I'm scared of log. :D
Now really, I can't even remember what it does (long gone are the math classes). Anyway, while fighting with this bad headache I've decided to release the function as is, for whatever use one may find to it. The BitRotate function topic can be found here.

Apologies for hijacking the thread, this is my last post on that topic. :oops:

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008

I'm scared of log. :D
Now really, I can't even remember what it does (long gone are the math classes).

The log function satisfies this equation (the "^" is the power operation - it is "**" in AHK)

n = 10^x
x = log(n)

If you want to use a different base, you divide, as tonne did, the log of the number by the log of the base.

Derivation:

2 = 10^y
y = log(2)


n = 2^x
n = (10^y)^x
n = 10^(x * y)

x * y = log(n)
x * log(2) = log(n)
x = log(n) / log(2)

I used to be a math major / tutor (so, don't work about hijacking - I love math derivations :D).


From here, x represents the base 2 exponent for n.
ex. 1 = 2^0, 256 = 2^8.

Since unsigned values work on 8 bit "boundaries", if x < 8, then n is one byte (8 bits).

2^0 <= n < 2^8
1 <= n < 256


Else if x < 16, then x is two bytes (a dword), etc. This is the logic tonne used.
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
Thank you for the detailed explanation. It amplified my headache a little, though. :)

Will see if this method is lighter and if so, apply it to the function (which nobody seems to have noticed/tried so far). :) But for now, a painkiller and some rest. ;)

animeaime
  • Members
  • 1045 posts
  • Last active: Jun 18 2011 04:44 AM
  • Joined: 04 Nov 2008
OK, as I wrap up the last bit of testing, you know what happens... I realize that AHK can do WAY too much. Allowing inputted values to be in hex form was easy enough (output will always be in decimal form), but now I face a question of how to handle the float format.

There will be an option to output the format in a specific float format (except scientific notation) - this has a separate option. There is also support to not round the result, by specifing "00" as an option. On a side note, specifing "0" would round to the nearest integer.

Currently, the "00" option would return the output in the format specified by the currently set float format - see the SetFormat command for details. If this is acceptable, there is no need to change anything. If not, could someone suggest what "no rounding" means to you - in a 50-100 word essay. :p
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.