Trying to print LDBL_MAX - long-double

I use CodeBlocks 20.03 with the embedded MinGW-W64 gcc compiler version 8.1.0 for Windows 10.
I am trying to print the LDBL_MIN and LDBL_MAX constants, normally in the range of 10e4932 but I get values in the range of 10e-317.
Here is my code:
#include <stdio.h>
#include <float.h>
main()
{
printf("Unit \"long double\" -> %i bytes -> range %Lf - %Lf.\n",\
sizeof(long double), LDBL_MIN, LDBL_MAX);
printf("Unit \"long double\" -> %i bytes -> range %Le - %Le.\n",\
sizeof(long double), LDBL_MIN, LDBL_MAX);
printf("Unit \"long double\" -> %i bytes -> range %Lg - %Lg.\n",\
sizeof(long double), LDBL_MIN, LDBL_MAX);
printf("Unit \"long double\" -> %i bytes -> range %LG - %LG.\n",\
sizeof(long double), LDBL_MIN, LDBL_MAX);
}
and the result:
Unit "long double" -> 16 bytes -> range 0.000000 - 0.000000.
Unit "long double" -> 16 bytes -> range 3.172905e-317 - 3.172897e-317.
Unit "long double" -> 16 bytes -> range 3.17291e-317 - 3.1729e-317.
Unit "long double" -> 16 bytes -> range 3.17291E-317 - 3.1729E-317.
Any idea why?
Thank you.

If you enable warnings by compiling your /tmp/xander.c with gcc -O -g /tmp/xander.c -o /tmp/xander -lm you could get (on Ubuntu 20, with GCC 9.3)
pcbasile ~ 13:23 % gcc -O -g /tmp/xander.c -o /tmp/xander -lm
/tmp/xander.c:4:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
4 | main()
| ^~~~
/tmp/xander.c: In function ‘main’:
/tmp/xander.c:6:38: warning: format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
6 | printf("Unit \"long double\" -> %i bytes -> range %Lf - %Lf.\n",\
| ~^
| |
| int
| %li
7 | sizeof(long double), LDBL_MIN, LDBL_MAX);
| ~~~~~~~~~~~~~~~~~~~
| |
| long unsigned int
/tmp/xander.c:8:38: warning: format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
8 | printf("Unit \"long double\" -> %i bytes -> range %Le - %Le.\n",\
| ~^
| |
| int
| %li
9 | sizeof(long double), LDBL_MIN, LDBL_MAX);
| ~~~~~~~~~~~~~~~~~~~
| |
| long unsigned int
/tmp/xander.c:10:38: warning: format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
10 | printf("Unit \"long double\" -> %i bytes -> range %Lg - %Lg.\n",\
| ~^
| |
| int
| %li
11 | sizeof(long double), LDBL_MIN, LDBL_MAX);
| ~~~~~~~~~~~~~~~~~~~
| |
| long unsigned int
/tmp/xander.c:12:38: warning: format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
12 | printf("Unit \"long double\" -> %i bytes -> range %LG - %LG.\n",\
| ~^
| |
| int
| %li
13 | sizeof(long double), LDBL_MIN, LDBL_MAX);
| ~~~~~~~~~~~~~~~~~~~
| |
| long unsigned int
pcbasile ~ 13:24 % gcc -O -g /tmp/xander.c -o /tmp/xander
So your format %i is wrong; once you replace %i with %zi the output looks better at runtime:
Unit "long double" -> 16 bytes -> range 0.000000 - 1189731495357231765021263853030970205169063322294624200440323733891737005522970722616410290336528882853545697807495577314427443153670288434198125573853743678673593200706973263201915918282961524365529510646791086614311790632169778838896134786560600399148753433211454911160088679845154866512852340149773037600009125479393966223151383622417838542743917838138717805889487540575168226347659235576974805113725649020884855222494791399377585026011773549180099796226026859508558883608159846900235645132346594476384939859276456284579661772930407806609229102715046085388087959327781622986827547830768080040150694942303411728957777100335714010559775242124057347007386251660110828379119623008469277200965153500208474470792443848545912886723000619085126472111951361467527633519562927597957250278002980795904193139603021470997035276467445530922022679656280991498232083329641241038509239184734786121921697210543484287048353408113042573002216421348917347174234800714880751002064390517234247656004721768096486107994943415703476320643558624207443504424380566136017608837478165389027809576975977286860071487028287955567141404632615832623602762896316173978484254486860609948270867968048078702511858930838546584223040908805996294594586201903766048446790926002225410530775901065760671347200125846406957030257138960983757998926954553052368560758683179223113639519468850880771872104705203957587480013143131444254943919940175753169339392366881856189129931729104252921236835159922322050998001677102784035360140829296398115122877768135706045789343535451696539561254048846447169786893211671087229088082778350518228857646062218739702851655083720992349483334435228984751232753726636066213902281264706234075352071724058665079518217303463782631353393706774901950197841690441824738063162828586857741432581165364040218402724913393320949219498422442730427019873044536620350262386957804682003601447291997123095530057206141866974852846856186514832715974481203121946751686379343096189615107330065552421485195201762858595091051839472502863871632494167613804996319791441870254302706758495192008837915169401581740046711477877201459644461175204059453504764721807975761111720846273639279600339670470037613374509553184150073796412605047923251661354841291884211340823015473304754067072818763503617332908005951896325207071673904547777129682265206225651439919376804400292380903112437912614776255964694221981375146967079446870358004392507659451618379811859392049544036114915310782251072691486979809240946772142727012404377187409216756613634938900451232351668146089322400697993176017805338191849981933008410985993938760292601390911414526003720284872132411955424282101831204216104467404621635336900583664606591156298764745525068145003932941404131495400677602951005962253022823003631473824681059648442441324864573137437595096416168048024129351876204668135636877532814675538798871771836512893947195335061885003267607354388673368002074387849657014576090349857571243045102038730494854256702479339322809110526041538528994849203991091946129912491633289917998094380337879522093131466946149705939664152375949285890960489916121944989986384837022486672249148924678410206183364627416969576307632480235587975245253737035433882960862753427740016333434055083537048507374544819754722228975281083020898682633020285259923084168054539687911418297629988964576482765287504562854924265165217750799516259669229114977788962356670956627138482018191348321687995863652637620978285070099337294396784639879024914514222742527006363942327998483976739987154418554201562244154926653014515504685489258620276085761837129763358761215382565129633538141663949516556000264159186554850057052611431952919918807954522394649627635630178580896692226406235382898535867595990647008385687123810329591926494846250768992258419305480763620215089022149220528069842018350840586938493815498909445461977893029113576516775406232278298314033473276603952231603422824717528181818844304880921321933550869873395861276073670866652375555675803171490108477320096424318780070008797346032906278943553743564448851907191616455141155761939399690767415156402826543664026760095087523945507341556135867933066031744720924446513532366647649735400851967040771103640538150073486891798364049570606189535005089840913826869535090066783324472578712196604415284924840041850932811908963634175739897166596000759487800619164094854338758520657116541072260996288150123144377944008749301944744330784388995701842710004808305012177123560622895076269042856800047718893158089358515593863176652948089031267747029662545110861548958395087796755464137944895960527975209874813839762578592105756284401759349324162148339565350189196811389091843795734703269406342890087805846940352453479398080674273236297887100867175802531561302356064878709259865288416350972529537091114317204887747405539054009425375424119317944175137064689643861517718849867010341532542385911089624710885385808688837777258648564145934262121086647588489260031762345960769508849149662444156604419552086811989770240.000000.
Unit "long double" -> 16 bytes -> range 3.362103e-4932 - 1.189731e+4932.
Unit "long double" -> 16 bytes -> range 3.3621e-4932 - 1.18973e+4932.
Unit "long double" -> 16 bytes -> range 3.3621E-4932 - 1.18973E+4932.
Remember that sizeof(int) is 4, but sizeof(sizeof(long double)) is like sizeof(long) 8 bytes

Related

Controlling parser rule alternatives precedence

I have an expression IF 1 THEN 2 ELSE 3 * 4. I want this parsed as IF 1 THEN 2 ELSE (3 * 4), however using my grammar (extract) below, it parses it as (IF 1 THEN 2 ELSE 3) * 4.
formula: expression EOF;
expression
: LPAREN expression RPAREN #parenthesisExp
| IF condition=expression THEN thenExpression=expression ELSE elseExpression=expression #ifExp
| left=expression BINARYOPERATOR right=expression #binaryoperationExp
| left=expression op=(TIMES|DIV) right=expression #muldivExp
| left=expression op=(PLUS|MINUS) right=expression #addsubtractExp
| left=expression op=(EQUALS|NOTEQUALS|LT|GT) right=expression #comparisonExp
| left=expression AMPERSAND right=expression #concatenateExp
| NOT expression #notExp
| STRINGLITERAL #stringliteralExp
| signedAtom #atomExp
;
My understanding is that because I have the ifExp alternative appearing before the muldivExp it should use that first, then because I have the muldivExp before atomExp (which handles numbers) it should do 3 * 4 to end the ELSE, rather than using just the 3. In which case I can't see why it's making the IF..THEN..ELSE a child of the multiplication.
I don't think the rest of the grammar is relevant here, but in case it is see below for the whole thing.
grammar AnaplanFormula;
formula: expression EOF;
expression
: LPAREN expression RPAREN #parenthesisExp
| IF condition=expression THEN thenExpression=expression ELSE elseExpression=expression #ifExp
| left=expression BINARYOPERATOR right=expression #binaryoperationExp
| left=expression op=(TIMES|DIV) right=expression #muldivExp
| left=expression op=(PLUS|MINUS) right=expression #addsubtractExp
| left=expression op=(EQUALS|NOTEQUALS|LT|GT) right=expression #comparisonExp
| left=expression AMPERSAND right=expression #concatenateExp
| NOT expression #notExp
| STRINGLITERAL #stringliteralExp
| signedAtom #atomExp
;
signedAtom
: PLUS signedAtom #plusSignedAtom
| MINUS signedAtom #minusSignedAtom
| func_ #funcAtom
| atom #atomAtom
;
atom
: SCIENTIFIC_NUMBER #numberAtom
| LPAREN expression RPAREN #expressionAtom // Do we need this?
| entity #entityAtom
;
func_: functionname LPAREN (expression (',' expression)*)? RPAREN #funcParameterised
| entity LSQUARE dimensionmapping (',' dimensionmapping)* RSQUARE #funcSquareBrackets
;
dimensionmapping: WORD COLON entity; // Could make WORD more specific here
functionname: WORD; // Could make WORD more specific here
entity: QUOTELITERAL #quotedEntity
| WORD+ #wordsEntity
| left=entity DOT right=entity #dotQualifiedEntity
;
WS: [ \r\n\t]+ -> skip;
/////////////////
// Fragments //
/////////////////
fragment NUMBER: DIGIT+ (DOT DIGIT+)?;
fragment DIGIT: [0-9];
fragment LOWERCASE: [a-z];
fragment UPPERCASE: [A-Z];
fragment WORDSYMBOL: [#?_£%];
//////////////////
// Tokens //
//////////////////
IF: 'IF' | 'if';
THEN: 'THEN' | 'then';
ELSE: 'ELSE' | 'else';
BINARYOPERATOR: 'AND' | 'and' | 'OR' | 'or';
NOT: 'NOT' | 'not';
WORD: (DIGIT* (LOWERCASE | UPPERCASE | WORDSYMBOL)) (LOWERCASE | UPPERCASE | DIGIT | WORDSYMBOL)*;
STRINGLITERAL: DOUBLEQUOTES (~'"' | ('""'))* DOUBLEQUOTES;
QUOTELITERAL: '\'' (~'\'' | ('\'\''))* '\'';
LSQUARE: '[';
RSQUARE: ']';
LPAREN: '(';
RPAREN: ')';
PLUS: '+';
MINUS: '-';
TIMES: '*';
DIV: '/';
COLON: ':';
EQUALS: '=';
NOTEQUALS: LT GT;
LT: '<';
GT: '>';
AMPERSAND: '&';
DOUBLEQUOTES: '"';
UNDERSCORE: '_';
QUESTIONMARK: '?';
HASH: '#';
POUND: '£';
PERCENT: '%';
DOT: '.';
PIPE: '|';
SCIENTIFIC_NUMBER: NUMBER (('e' | 'E') (PLUS | MINUS)? NUMBER)?;
Move your ifExpr down near the end of your alternatives. (In particular, below any alternative that you would wish to match your elseExpression
Your “if ... then ... else ...” is below the muldivExp precisely because you've made it a higher priority. Items lower in the tree are evaluated before items higher in the tree, so higher priority items belong lower in the tree.
With:
expression:
LPAREN expression RPAREN # parenthesisExp
| left = expression BINARYOPERATOR right = expression # binaryoperationExp
| left = expression op = (TIMES | DIV) right = expression # muldivExp
| left = expression op = (PLUS | MINUS) right = expression # addsubtractExp
| left = expression op = (EQUALS | NOTEQUALS | LT | GT) right = expression # comparisonExp
| left = expression AMPERSAND right = expression # concatenateExp
| NOT expression # notExp
| STRINGLITERAL # stringliteralExp
| signedAtom # atomExp
| IF condition = expression THEN thenExpression = expression ELSE elseExpression = expression #
ifExp
;
I get

Big loop in Solidity

I calculate price by this loop
uint tokenPrice = 1e15;
uint tokenPriceStep = 1e11;//
uint sendValue = 3e18; //3 ETH
uint balance = 0;
do {
balance += 1e18;
sendValue -= tokenPrice;
tokenPrice += tokenPriceStep;
} while (sendValue > tokenPrice);
if(sendValue > 0){
balance += sendValue * 1e18 / tokenPrice;
tokenPrice += (sendValue * 1e18 / tokenPrice) * tokenPriceStep / 1e18;
sendValue = 0;
}
But this is cost to much gas. And REMIX just crashed when i run this. What can i must do? I need this loop to calculate price like this:
For example logics looks like this:
First colum is number
Second colum is my value (my money)
Third is my token balance
Forth colum is price (that grow by 1 or any else)
0 - 3000.00000 -> 0.00000 -> 100.00000
1 - 2900.00000 -> 1.00000 -> 101.00000
2 - 2799.00000 -> 2.00000 -> 102.00000
3 - 2697.00000 -> 3.00000 -> 103.00000
4 - 2594.00000 -> 4.00000 -> 104.00000
5 - 2490.00000 -> 5.00000 -> 105.00000
6 - 2385.00000 -> 6.00000 -> 106.00000
7 - 2279.00000 -> 7.00000 -> 107.00000
8 - 2172.00000 -> 8.00000 -> 108.00000
9 - 2064.00000 -> 9.00000 -> 109.00000
10 - 1955.00000 -> 10.00000 -> 110.00000
11 - 1845.00000 -> 11.00000 -> 111.00000
12 - 1734.00000 -> 12.00000 -> 112.00000
13 - 1622.00000 -> 13.00000 -> 113.00000
14 - 1509.00000 -> 14.00000 -> 114.00000
15 - 1395.00000 -> 15.00000 -> 115.00000
16 - 1280.00000 -> 16.00000 -> 116.00000
17 - 1164.00000 -> 17.00000 -> 117.00000
18 - 1047.00000 -> 18.00000 -> 118.00000
19 - 929.00000 -> 19.00000 -> 119.00000
20 - 810.00000 -> 20.00000 -> 120.00000
21 - 690.00000 -> 21.00000 -> 121.00000
22 - 569.00000 -> 22.00000 -> 122.00000
23 - 447.00000 -> 23.00000 -> 123.00000
24 - 324.00000 -> 24.00000 -> 124.00000
25 - 200.00000 -> 25.00000 -> 125.00000
26 - 75.00000 -> 26.00000 -> 126.00000
27 - 0.00000 -> 26.59524 -> 126.59524
Please help, i can't know what to do!
I think you can do it like this without a loop:
uint times = sendValue / tokenPrice; // this is how many time the loop would run
balance += times * (1e18);
tokenPrice += times * tokePriceStep;
sendValue -= times * tokenPrice;
After that the rest is the same.
You should always try to avoid loops in your contract since it is very easy to run out of gas or sometimes even exceed the block's gas limit.

ANTLR4 Grammar Performance Very Poor

Given the grammar below, I'm seeing very poor performance when parsing longer strings, on the order of seconds. (this on both Python and Go implementations) Is there something in this grammar that is causing that?
Example output:
0.000061s LEXING "hello world"
0.014349s PARSING "hello world"
0.000052s LEXING 5 + 10
0.015384s PARSING 5 + 10
0.000061s LEXING FIRST_WORD(WORD_SLICE(contact.blerg, 2, 4))
0.634113s PARSING FIRST_WORD(WORD_SLICE(contact.blerg, 2, 4))
0.000095s LEXING (DATEDIF(DATEVALUE("01-01-1970"), date.now, "D") * 24 * 60 * 60) + ((((HOUR(date.now)+7) * 60) + MINUTE(date.now)) * 60))
1.552758s PARSING (DATEDIF(DATEVALUE("01-01-1970"), date.now, "D") * 24 * 60 * 60) + ((((HOUR(date.now)+7) * 60) + MINUTE(date.now)) * 60))
This is on Python.. though I don't expect blazing performance I would expect sub-second for any input. What am I doing wrong?
grammar Excellent;
parse
: expr EOF
;
expr
: atom # expAtom
| concatenationExpr # expConcatenation
| equalityExpr # expEquality
| comparisonExpr # expComparison
| additionExpr # expAddition
| multiplicationExpr # expMultiplication
| exponentExpr # expExponent
| unaryExpr # expUnary
;
path
: NAME (step)*
;
step
: LBRAC expr RBRAC
| PATHSEP NAME
| PATHSEP NUMBER
;
parameters
: expr (COMMA expr)* # functionParameters
;
concatenationExpr
: atom (AMP concatenationExpr)? # concatenation
;
equalityExpr
: comparisonExpr op=(EQ|NE) comparisonExpr # equality
;
comparisonExpr
: additionExpr (op=(LT|GT|LTE|GTE) additionExpr)? # comparison
;
additionExpr
: multiplicationExpr (op=(ADD|SUB) multiplicationExpr)* # addition
;
multiplicationExpr
: exponentExpr (op=(MUL|DIV) exponentExpr)* # multiplication
;
exponentExpr
: unaryExpr (EXP exponentExpr)? # exponent
;
unaryExpr
: SUB? atom # negation
;
funcCall
: function=NAME LPAR parameters? RPAR # functionCall
;
funcPath
: function=funcCall (step)* # functionPath
;
atom
: path # contextReference
| funcCall # atomFuncCall
| funcPath # atomFuncPath
| LITERAL # stringLiteral
| NUMBER # decimalLiteral
| LPAR expr RPAR # parentheses
| TRUE # true
| FALSE # false
;
NUMBER
: DIGITS ('.' DIGITS?)?
;
fragment
DIGITS
: ('0'..'9')+
;
TRUE
: [Tt][Rr][Uu][Ee]
;
FALSE
: [Ff][Aa][Ll][Ss][Ee]
;
PATHSEP
:'.';
LPAR
:'(';
RPAR
:')';
LBRAC
:'[';
RBRAC
:']';
SUB
:'-';
ADD
:'+';
MUL
:'*';
DIV
:'/';
COMMA
:',';
LT
:'<';
GT
:'>';
EQ
:'=';
NE
:'!=';
LTE
:'<=';
GTE
:'>=';
QUOT
:'"';
EXP
: '^';
AMP
: '&';
LITERAL
: '"' ~'"'* '"'
;
Whitespace
: (' '|'\t'|'\n'|'\r')+ ->skip
;
NAME
: NAME_START_CHARS NAME_CHARS*
;
fragment
NAME_START_CHARS
: 'A'..'Z'
| '_'
| 'a'..'z'
| '\u00C0'..'\u00D6'
| '\u00D8'..'\u00F6'
| '\u00F8'..'\u02FF'
| '\u0370'..'\u037D'
| '\u037F'..'\u1FFF'
| '\u200C'..'\u200D'
| '\u2070'..'\u218F'
| '\u2C00'..'\u2FEF'
| '\u3001'..'\uD7FF'
| '\uF900'..'\uFDCF'
| '\uFDF0'..'\uFFFD'
;
fragment
NAME_CHARS
: NAME_START_CHARS
| '0'..'9'
| '\u00B7' | '\u0300'..'\u036F'
| '\u203F'..'\u2040'
;
ERRROR_CHAR
: .
;
You can always try to parse with SLL(*) first and only if that fails you need to parse it with LL(*) (which is the default).
See this ticket on ANTLR's GitHub for further explaination and here is an implementation that uses this strategy.
This method will save you (a lot of) time when parsing syntactically correct input.
Seems like this performance is due to the left recursion used in the addition / multiplication etc, operators. Rewriting these to be binary rules instead yields performance that is instant. (see below)
grammar Excellent;
COMMA : ',';
LPAREN : '(';
RPAREN : ')';
LBRACK : '[';
RBRACK : ']';
DOT : '.';
PLUS : '+';
MINUS : '-';
TIMES : '*';
DIVIDE : '/';
EXPONENT : '^';
EQ : '=';
NEQ : '!=';
LTE : '<=';
LT : '<';
GTE : '>=';
GT : '>';
AMPERSAND : '&';
DECIMAL : [0-9]+('.'[0-9]+)?;
STRING : '"' (~["] | '""')* '"';
TRUE : [Tt][Rr][Uu][Ee];
FALSE : [Ff][Aa][Ll][Ss][Ee];
NAME : [a-zA-Z][a-zA-Z0-9_.]*; // variable names, e.g. contact.name or function names, e.g. SUM
WS : [ \t\n\r]+ -> skip; // ignore whitespace
ERROR : . ;
parse : expression EOF;
atom : fnname LPAREN parameters? RPAREN # functionCall
| atom DOT atom # dotLookup
| atom LBRACK expression RBRACK # arrayLookup
| NAME # contextReference
| STRING # stringLiteral
| DECIMAL # decimalLiteral
| TRUE # true
| FALSE # false
;
expression : atom # atomReference
| MINUS expression # negation
| expression EXPONENT expression # exponentExpression
| expression (TIMES | DIVIDE) expression # multiplicationOrDivisionExpression
| expression (PLUS | MINUS) expression # additionOrSubtractionExpression
| expression (LTE | LT | GTE | GT) expression # comparisonExpression
| expression (EQ | NEQ) expression # equalityExpression
| expression AMPERSAND expression # concatenation
| LPAREN expression RPAREN # parentheses
;
fnname : NAME
| TRUE
| FALSE
;
parameters : expression (COMMA expression)* # functionParameters
;

How to increment a counter when a value is found in awk

I am trying to write an awk script. part of the code needs to count the number of times $10 (in the code below its 256) is a certain value.
The possibilities are 4, 8, 16, 32, 64, 128, 256
Each time one of these values appears I want a corresponding variable to be incremented by one.
My block of code is
{
if ($10 == "4") {bs_4k++}
else if ($10 == "8") {bs_8k++}
if ($10 == "16") {bs_16k++}
if ($10 == "32") {bs_32k++}
if ($10 == "64") {bs_64k++}
if ($10 == "128") {bs_128k++}
if ($10 == "256") {bs_256k++}
};
This is the format of the data:
259,0 23 1 0.000000000 0 C WS 167588096 + 256 [0]
259,0 23 2 0.000002073 0 C WS 167588352 + 256 [0]
259,0 23 3 0.000004040 0 C WS 167587840 + 256 [0]
And my code to print results:
END {
print "Number of 256k blocks: " 256k_bs;
print "Number of 128k blocks: "128k_bs;
print "Number of 64k blocks: " 64k_bs;
print "Number of 32k blocks: " 32k_bs;
print "Number of 16k blocks: " 16k_bs;
print "Number of 8k blocks: " 8k_bs;
print "Number of 4k blocks: " 4k_bs;
};
When I try to print the variable I get:
Number of 256k blocks: 256
Number of 128k blocks: 128
Number of 64k blocks: 64
Number of 32k blocks: 32
Number of 16k blocks: 16
Number of 8k blocks: 8
Number of 4k blocks: 4
Any help is appreciated.
An easier way to hadnle this in awk might be to use an array instead of a collection of distinct variables.
Using this awk script:
BEGIN{
for (i=4;i<=256;i=i*2) { valid[i] }
}
$10 in valid {
bs[$10]++
}
END {
for (n in bs) {
printf("Number of %dk blocks: %d\n", n, bs[n])
}
}
on the following input data:
259,0 23 1 0.000000000 0 C WS 167588096 + 256 [0]
259,0 23 2 0.000002073 0 C WS 167588352 + 256 [0]
259,0 23 3 0.000004040 0 C WS 167587840 + 256 [0]
259,0 23 3 0.000004040 0 C WS 167587000 + 32 [0]
259,0 23 3 0.000004040 0 C WS 167587001 + 64 [0]
gets me the following results:
$ awk -f i.awk input.txt
Number of 64k blocks: 1
Number of 32k blocks: 1
Number of 256k blocks: 3
Of course, if you want the output sorted, you can pipe it through sort, or structure your awk array differently. Such additions are left as an exercise for the reader. :-)
You're not using your variables in the END block. As such, the numeric part is being interpreted literally, then a variable k_bs is being evaluated (which is unset, so you get an empty string).
Change 256k_bs to bs_256k, etc.
you can achieve the same with unit toolset
$ cut -d' ' -f10 file | sort -nr | uniq -c
3 256
1 64
1 32
and format the result as desired.

F# HashCode to enum conversion

I have an enum of bit-masked error codes with a string representation and an binary int representation:
type ErrorCodes =
| NoError = 0
| InvalidInputError = 1
| AuthenticationFailedError = 2
| InvalidArgumentError = 4
| ItemNotFoundError = 8
| UnknownError = 16
As I run through the program, I collect all the errors by using the bitwise OR operator (|||). So now I have something that looks like 01100. How can I print to the console: "InvalidArgumentError", and "ItemNotFoundError?"
I had an idea of just using:
for i = 0 to 32 do
if ((err.GetHashCode() % 2) = 1) then
Console.WriteLine("ErrorCode: {0}",err.GetHashCode())
But now I'm stuck on how to print the actual string
If you decorate your ErrorCodes type with the System.Flags attribute then .ToString will format as a list of value names.
[<System.Flags>]
type ErrorCodes = ...
let errors = ErrorCodes.InvalidInputError ||| ErrorCodes.UnknownError
printfn "%O" errors
If, for whatever reason, you don't want the default flags ToString implementation, you could do something like this:
let inline printFlags (flags: 'e) =
let ty = typeof<'e>
(Enum.GetValues ty :?> 'e[], Enum.GetNames ty)
||> Array.zip
|> Seq.filter (fun (v, _) -> v <> enum 0 && flags &&& v = v)
|> Seq.iter (snd >> printfn "%s")
printFlags (ErrorCodes.InvalidInputError ||| ErrorCodes.UnknownError)
Output:
InvalidInputError
UnknownError