I'm trying to do some floating-point math in a zsh script. I'm seeing the following behavior:
$ (( a = 1.23456789 * 0.00000001 )); printf "a = %g\n" $a
a = 1.23e-08
$ (( a = 1.23456789 * 0.00000001 )); printf "a = %e\n" $a
a = 1.230000e-08
$ (( a = 1.23456789 * 0.0000001 )); printf "a = %e\n" $a
a = 1.235000e-07
I expect not to loose the 1st number's mantissa precision when I merely multiply it by a number whose mantissa is 1 (or at least very close to 1, if the true binary representation is considered). In other words, I'd expect to get a = 1.23456789e-08 or maybe some truncated mantissa, but not zeros after 1.23 / 1.235.
I'm running the following version:
$ zsh --version
zsh 5.8 (x86_64-apple-darwin20.0)
Am I missing something? Or is it an issue in zsh? I'm new to zsh, and I don't have a lot of experience in shell programming in general, so any help is appreciated. Thanks!
It appears that (( x = 1.0 )), when x is not defined, will cause Zsh to declare the variable as -F: a double precision floating point which is formatted to fixed-point with 10 decimal digits on output:
% unset x; (( x = 0.12345678901234567 )); declare -p x
typeset -F x=0.1234567890
% unset x; x=$((0.12345678901234567)); declare -p x
typeset x=0.12345678901234566
I don't know why it works this way, but if you manually declare your variable as a string first, this won't happen, and you'll get the full value:
% unset a; typeset a; (( a = 1.23456789 * 0.00000001 )); printf "a = %g\n" $a
a = 1.23457e-08
The difference comes from the way of how you pass the value of a to printf. If you write it as
(( a = 1.23456789 * 0.00000001 )); printf "a = %e\n" $((a))
$ (( a = 1.23456789 * 0.0000001 )); printf "a = %e\n" $((a))
the problem does not occur. This is described here, where it says:
floating point numbers can be declared with the float builtin; there are two types, differing only in their output format, as described for the typeset builtin. The output format can be bypassed by using arithmetic substitution instead of the parameter substitution, i.e. ‘${float}’ uses the defined format, but ‘$((float))’ uses a generic floating point format
Related
Problem when using variable
echo ""| awk '{
x=-0.35
print x^1.35
print -0.35^1.35
}'
Result
+nan
-0.242377
Using GNU awk
The output is correct.
The power operator ^ has higher precedence than the negation operator. Therefore, x^1.35 is (-0.35)^1.35 (a negative number to a non-integer power is a complex number, interpreted as a -nan), but -0.35^1.35 is -(0.35^1.35), a negated positive power of a positive number.
In college, I was required to take a whole semester on complex math, here is the mathematical meat of this issue:
-0.35^1.35 =
-0.35^(135/100) =
-0.35^(27/20) =
((-0.35^27))^1/20) =
(-0.00000000000049)^1/20 =
0.242377253454738i (or "nan" if constrained to real #s)
-0.35^1.35 =
-0.35^(135/100) =
-0.35^(27/20) =
-0.35^(54/40) =
((-0.35^54))^1/40) =
(2.397035107846411e-25)^1/40 =
0.242377253454738
-- so, the answer is there are two answers! Your new word for the day is "complex conjugate".
In the following Julia 1.5 code:
a, b = 4, 5
"a=$(a), b=($b)" # "a=4, b=5"
using Markdown
md"a=$(a), b=($b)" # a=a, b=b
# but...
Markdown.parse("a=$(a), b=($b)") # "a=4, b=5"
It seems that the Markdown macro thinks two $ indicate a math expression. But the parse handles it OK.
Can someone explain this? is there a way to use the md"..." form for this.
It's not obvious in my opinion, but I think $ with a non-space before is interpreted as a closing LaTeX $ if there is one before.
Some suggestions:
If you're OK with spaces around your = sign, then this works:
julia> md"a = $a, b = $b"
a = 4, b = 5
Or you could make it a list:
julia> md"""
- a=$a
- b=$b
"""
• a=4
• b=5
In my equations we have many expressions with a^2, and so on. I would like to map "²" to ^2, to obtain something like that:
julia> a² == a^2
true
The above is not however a legal code in Julia. Any idea on how could I implement it ?
Here is a sample macro #hoo that does what you requested in a simplified scenario (since the code is long I will start with usage).
julia> x=5
5
julia> #hoo 3x² + 4x³
575
julia> #macroexpand #hoo 2x³+3x²
:(2 * Main.x ^ 3 + 3 * Main.x ^ 2)
Now, let us see the macro code:
const charsdict=Dict(Symbol.(split("¹²³⁴⁵⁶⁷⁸⁹","")) .=> 1:9)
const charsre = Regex("[$(join(String.(keys(charsdict))))]")
function proc_expr(e::Expr)
for i=1:length(e.args)
el = e.args[i]
typeof(el) == Expr && proc_expr(el)
if typeof(el) == Symbol
mm = match(charsre, String(el))
if mm != nothing
a1 = Symbol(String(el)[1:(mm.offset-1)])
a2 = charsdict[Symbol(mm.match)]
e.args[i] = :($a1^$a2)
end
end
end
end
macro hoo(expr)
typeof(expr) != Expr && return expr
proc_expr(expr)
expr
end
Of course it would be quite easy to expand this concept into "pure-math" library for Julia.
I don't think that there is any reasonable way of doing this.
When parsing your input, Julia makes no real difference between the unicode character ² and any other characters you might use in a variable name. Attempting to make this into an operator would be similar to trying to make the suffix square into an operator
julia> asquare == a^2
The a and the ² are not parsed as two separate things, just like the a and the square in asquare would not be.
a^2, on the other hand, is parsed as three separate things. This is because ^ is not a valid character for a variable name and it is therefore parsed as an operator instead.
I have created a small code in Julia that is able to use function iteration to solve a simple non-linear problem.
The code is the following:
"""
Problem: find the root of f(x) = exp(-x) - x
using the fixed point iteration
(aka function iteration)
Solution: f(x) = exp(-x) - x = 0
x = exp(-x)
"""
i = 0; # initialize first iteration
x = 0; # initialize solution
error = 1; # initialize error bound
xvals = x; # initialize array of iterates
tic()
while error >= 1e-10
y = exp(-x);
xvals = [xvals;y]; # It is not needed actually
error = abs(y-x);
x = y;
i = i + 1;
println(["Solution", x', "Error:", error', "Iteration no:", i'])
end
toc()
In the above code the results are not neat for there are many decimal numbers. To my understanding, using println may not be a good idea and instead #printf or sprintf must be used, however, I was not able to put everything in one line.
Is it possible to do that?
The syntax for printf is (roughly) the same for all languages,
but it is indeed arcane.
You can use %f for floats, %e for floats in scientific notation,
%d for integers, %s for strings.
The numbers between the % and the letter are
the number of digits (or characters) before and after the comma.
i = 0
x = 0
error = Inf
while error >= 1e-10
x, previous = exp(-x), x
error = abs( x - previous )
i += 1
#printf(
"Value: %1.3f Error: %1.3e Iteration: %3d\n",
x, error, i
)
end
You could also have tried round or signif,
but since round decimal numbers cannot always be represented exactly as floats,
that does not work reliably.
I am learning Jason Hickey's Introduction to Objective Caml.
Just have a question about Redefine the infix operators.
So in the book, there is such a paragraph:
# let (+) = ( * )
and (-) = (+)
and ( * ) = (/)
and (/) = (-);;
val + : int > int > int = <fun>
val - : int > int > int = <fun>
val * : int > int > int = <fun>
val / : int > int > int = <fun>
# 5 + 4 / 1;;
-: **int = 15**
First, how does these redefinition work?
To me, it seems the functions are running in a kind of indefinite loop, because all the operations seem redefined and connected.
for example, if I do 1+2, then it will be 1 * 2 and since ( * ) = (/), it will be then 1 / 2 and since (/) = (-), then it will be 1-2, so on so forth. Am I right?
Second, will the result of 5 + 4 / 1 be 15, even if the functions are executed only one step further in the redefinition?
So assume the redefinition will be execute one step further, i.e., 1 + 2 will only be 1 * 2 and no more transform, so 5 + 4 / 1 should be 5 * 4 -1, right? then the answer is 19. Am I correct?
To me, it seems the functions are running in a kind of indefinite
loop, because all the operations seem redefined and connected.
Not really, it's just a simultaneous re-definition of infix operators (with the and keyword). What you see is not a recursive definition. In OCaml, recursive definitions are made with let rec (as you may already know).
For the second part of the question, I think it's a matter of operator precedence. Note that in the original expression 5 + 4 / 1 is actually 5 + (4/1) following the usual precedence rules for arithmetic operators. So, I think the conversion simply preserves this binding (sort of). And you get 5 * (4 - 1) = 15.
The key observation (IMHO) is that (+) is being defined by the preexisting definition of ( * ), not by the one that appears a few lines later. Similarly, ( * ) is being defined by the preexisting definition of (/). As Asiri says, this is because of the use of let rather than let rec.
It's also true that in OCaml, precedence and associativity are inherent in the operators and can't be changed by definitions. Precedence and associativity are determined by the first character of the operator.
If you look at the table of operator precedences and associativities in Section 6.7 of the OCaml Manual, you'll see that all the entries are defined for "operators beginning with character X".