How to print uint64_t properly in D language (dtrace) - printf

I'm trying to printf some Solaris kernel level information with the type of uint64_t (e.g. timestamp) using a DTrace script. How I can print uint64_t safely and precisely in my DTrace code.
I know the proper way of printing uint64_t in C is:
#define __STDC_FORMAT_MACROS
#include <sys/inttypes.h> //sys: Kernel level
uint64_t timestamp;
printf("%"PRIu64"\n", timestamp);
What's an equivalent in DTrace D? (%d and `%llu are imprecise and dangerous).
NOTE Not to be confused with other programming languages named "D" (a C++-like programming language developed by Walter Bright).

According to DTrace Wiki: Output Formatting:
The D compiler does not require the use of size prefixes with printf format conversions.
The C printf routine requires that you indicate the size of arguments by adding prefixes such as %ld for long or %lld for long long.
The D compiler knows the size and type of your arguments, so these prefixes are not required in your D printf statements.
Moreover, the %d and %i formats in D will handle either signed or unsigned ints, so you can use any of %d, %i, or %u to print an unsigned integer value in base 10, all with the same results.
The OP asked in a comment about the %Y format. This can be used for a uint64_t value that contains the number of nanoseconds since the Jan 1 1970 epoch, e.g. the built-in walltimestamp variable. (timestamp and vtimestamp are not counted from that epoch.)
The uint64_t argument is interpreted to be the number of nanoseconds since 00:00 Universal Coordinated Time, January 1, 1970, and is printed in the following cftime(3C) form: "%Y %a %b %e %T %Z."

Related

Formatting in Raku

I have written a function that outputs a double, upto 25 decimal
places. I am trying to print it as a formatted output from Raku.
However, the output is incorrect and truncated.
See MWE:
my $var = 0.8144262510988963255087469;
say sprintf("The variable value is: %.25f", $var)
The above code gives The variable value is: 0.8144262510988963000000000 which is not what is expected.
Also, this seems weird:
my $var = 0.8144262510988963255087469;
say $var.Str.chars; # 29 wrong, expected 27
I tested the same in C:
#include <stdio.h>
int main() {
double var = 0.8144262510988963255087469;
printf("The variable value is: %.25lf \n", var);
return 0;
}
However, it works fine. Given the identical nature of sprintf and printf, I expected this C example to work in Raku too. Seems like %lf is not supported.
So is there a workaround to fix this?
I think this is actually a bug in how Rat literals are created. Or at least as WAT :-).
I actually sort of expect 0.8144262510988963255087469 to either give a compile time warning, or create a Num, as it exceeds the standard precision of a Rat:
raku -e 'say 0.8144262510988963255087469'
0.814426251098896400086204416
Note that these are not the same.
There is fortunately an easy workaround, by creating a FatRat
$ raku -e 'say 0.8144262510988963255087469.FatRat'
0.8144262510988963255087469
FWIW, I think this is worthy of creating an issue
From your question:
I have written a function that outputs a double, upto 25 decimal places.
From google:
Double precision numbers are accurate up to sixteen decimal places
From the raku docs :
When constructing a Rat (i.e. when it is not a result of some mathematical expression), however, a larger denominator can be used
so if you go
my $v = 0.8144262510988963255087469;
say $v.raku;
#<8144262510988963255087469/10000000000000000000000000>
it works.
However, do a mathematical expression such as
my $b = $a/10000000000000000000000000;
and you get the Rat => Num degradation applied unless you explicitly declare FatRats. I visualise this as the math operation placing the result in a Num register in the CPU.
The docs also mention that .say and .put may be less faithful than .raku, presumably because they use math operations (or coercion) internally.
Sorry to be the bearer of bad news, but 10**25 > 2 **64, but what you report as an issue is correct & (fairly) well documented behaviour given the constraints of double precision IEEE P754.

Can I make printf format floats like C++ streams

I am comparing the output of two programs, one C the other C++, using diff, so the output must be identical.
Is there any way to printf a double so that it is formatted as though it was printed using << mydouble.
I am currently using printf("%g",mydouble)
Here are some examples of the differences:
c: 3.24769e-05 c++: 3.2477e-05
c: 0.0026572 c++: 0.00265721
Interestingly the scientific notation has more digits in c, and the decimal notation has more in c++.
You can solve this by using the format specifiers in C.
For example, say you would like to print out only 3 places after the decimal, you could make your printf like so:
printf("%.3lf", dub);
With a value of double dub = .0137; the output would be 0.014
This would fix the issue with your 2nd case if you want more precision printed you could write:
printf("%.8lf", dub);
Your output for double dub = 0.00265721; would then be 0.00265721
The case for %g works the same way except the number on the left is included in the calculation. If you wanted the C++ version (the lesser precision I assume) then your code would look like this:
double dub = .0000324769;
printf("%.5g", dub);
Which yields 3.2477e-05

List of printing format in Go lang

Just want to know the list of printing format using the fmt package's functions.
For example, like:
%v is use for print the value.
%T can print the type of value.
What else?
The list of format "verbs" is available in the documentation of the fmt package :
General:
%v the value in a default format.
when printing structs, the plus flag (%+v) adds field names
%#v a Go-syntax representation of the value
%T a Go-syntax representation of the type of the value
%% a literal percent sign; consumes no value
Boolean:
%t the word true or false
Integer:
%b base 2
%c the character represented by the corresponding Unicode code point
%d base 10
%o base 8
%q a single-quoted character literal safely escaped with Go syntax.
%x base 16, with lower-case letters for a-f
%X base 16, with upper-case letters for A-F
%U Unicode format: U+1234; same as "U+%04X"
Floating-point and complex constituents:
%b decimalless scientific notation with exponent a power of two,
in the manner of strconv.FormatFloat with the 'b' format,
e.g. -123456p-78
%e scientific notation, e.g. -1234.456e+78
%E scientific notation, e.g. -1234.456E+78
%f decimal point but no exponent, e.g. 123.456
%g whichever of %e or %f produces more compact output
%G whichever of %E or %f produces more compact output
String and slice of bytes:
%s the uninterpreted bytes of the string or slice
%q a double-quoted string safely escaped with Go syntax
%x base 16, lower-case, two characters per byte
%X base 16, upper-case, two characters per byte
Pointer:
%p base 16 notation, with leading 0x
Other flags:
+ always print a sign for numeric values;
guarantee ASCII-only output for %q (%+q)
- pad with spaces on the right rather than the left (left-justify the field)
# alternate format: add leading 0 for octal (%#o), 0x for hex (%#x);
0X for hex (%#X); suppress 0x for %p (%#p);
print a raw (backquoted) string if possible for %q (%#q);
write e.g. U+0078 'x' if the character is printable for %U (%#U).
' ' (space) leave a space for elided sign in numbers (% d);
put spaces between bytes printing strings or slices in hex (% x, % X)
0 pad with leading zeros rather than spaces
You can find out more, check this out http://golang.org/pkg/fmt/
and run
$ godoc -http=0.0.0.0:8080
browser open localhost:8080 to get entire offline go website (also including your go src & doc)

Rounding doubles for use in NSString

I have a situation where I have lots of different double values, for example 1.00, 0.25 and 2.50. I would like to round these doubles so that they become 1, 0.25 and 2.5; in other words I want to remove any trailing 0's. Is there a way to do this?
At the moment I have been using %.2f, and I'm wondering if I can make use of this but adapt it in some way. Please can someone help me out?
As long as you're talking only about display, this is quite easy. The format specifier you want is %g:
The double argument shall be converted in the style f or e (or in the style F or E in the case of a G conversion specifier), with the precision specifying the number of significant digits [...] Trailing zeros shall be removed from the fractional portion of the result[...]
double twopointfive = 2.500;
double onepointzero = 1.0;
double pointtwofive = .25000000000;
NSLog(#"%g %f", twopointfive, twopointfive);
NSLog(#"%g %f", onepointzero, onepointzero);
NSLog(#"%g %f", pointtwofive, pointtwofive);
2011-12-06 21:27:59.180 TrailingZeroes[39506:903] 2.5 2.500000
2011-12-06 21:27:59.184 TrailingZeroes[39506:903] 1 1.000000
2011-12-06 21:27:59.185 TrailingZeroes[39506:903] 0.25 0.250000
The same format specifier can be used with an NSNumberFormatter, which will also give you some control over significant digits.
The trailing zeroes can't be removed from the way the number is stored in memory, of course.
I believe you want the %g format specifier to redact trailing zeros.
Not really rounding, but have you tried just %f it should only show the number of digits required rather then padding out the number.
My answer above is wrong, %g as others has stated is the right way to go.
The documentation for string formatters should help too. http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265
Here is a list of all the format specifiers that you can use...
%# Object
%d, %i signed int
%u unsigned int
%f float/double
%x, %X hexadecimal int
%o octal int
%zu size_t
%p pointer
%e float/double (in scientific notation)
%g float/double (as %f or %e, depending on value)
%s C string (bytes)
%S C string (unichar)
%.*s Pascal string (requires two arguments, pass pstr[0] as the first, pstr+1 as the second)
%c character
%C unichar
%lld long long
%llu unsigned long long
%Lf long double

Question about #define statement in Objective-C project

I'm not experienced in C, so I'm not comfortable with this statement in this C / objective-C project.
#define CBLog(...) NSLog(#"%s [%ld]: %#", basename(__FILE__), __LINE__, [NSString stringWithFormat:__VA_ARGS__])
Questions:
the 3 dots (...) are used to indicate CBLog() is a method with parameters ? What do they mean ?
%ld stands for line format ? what's the d in %ld for ?
FILE , LINE and VA_ARGS are default replacement tokens for the C debugger ?
thanks
The ... means the macro accepts any number of arguments.
%ld is a string formatter meaning 'long decimal', where decimal really means integer.
__FILE__ expands to the current file name
__LINE__ expands to the current line number
__VA_ARGS__ expands to the arguments passed to the macro.
The debugger has nothing to do with it. All of this is the preprocessor, except %ld which is string formatting.
... means that any number of arguments can be given.
%ld means signed long, though it's a bit strange as I've never seen signed line numbers.
__FILE__ is the current source file's filename. __LINE__ is the current line number. __VA_ARGS__ are the arguments given to the macro.