I have a clue, why the expansion method of any value of say an x base always converts in decimal base. For example,
why if 2345 base 9 when apply the expansion method will always come to a value of base 10. Similar if we take 6577 base 8 (octal) applying expansion method i.e (6 * 8^3)+(5 * 8^2)+ (7 * 8^1)+(7 * 8^0) will systematically result to 3455 to base 10 !!! My question is why base 10 and not for example base 16....why is it systematically a decimal when using the expansion method of any base????
You are mixing number itself and its representation for human's convenience.
We usually use decimal system as traditional one for representation of numbers as strings (literals). But number value is the same in any system
01111(bin) = 15(dec) = F(hex) = 17(oct) = 100010 (fibonacci) and so on
why is it systematically a decimal when using the expansion method of any base????
I'm gonna flip this qustion for you: Why do YOU systematically keep using decimal?
You claim that 6 * 8^3 = 3072, I claim that 6 * 8^3 = C00. In fact I also claim that 6 * 8^3 = 4183. Why not 11 * 13^3 = 44242? Or 20 * 22^10 = 11012210? They're all correct.
You and only you chose to interpret the digits and perform arithmetic base 10.
Related
From an exponent xa, I am trying to get 'a' without a known value of 'x' using logarithm law logx(xa) = a
Originally I tried:
from sympy import *
x = Symbol('x')
print(log(x,x))
Which returns 1 as expected. But when raised to any other power, does not give single value e.g.
print(log(x**2,x))
Which returns:
log(x**2)/log(x)
instead of 2.
Is there any alternative way to get the exponent or fix to my original code?
If you use expand it will give you the result you are looking for. In addition, you can just get the exponent directly:
>>> log(x**2,x).expand() # or expand_log(log(x**2,x))
2
>>> (x**2).exp
2
>>> (x**2).as_base_exp()[1] # works for x**1, too, which is not a Pow
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
i know how to convert from base b to decimal but Im not understand what is base-b exactly. I know we multiply the base to the numbers if we gonna convert to bas 10 then multiply with then is base-b(base 5)?
In order to follow this, we should understand the difference between a number and its representation. Let's start with the (natural) numbers. There are two special numbers: zero and one. Zero is the neutral element of addition (i.e. you can add zero to anything without changing it) and one is the neutral element of multiplication. Every other number can be induced by these two numbers. Start with zero. Then, subsequently add one.
A common representation for numbers is the decimal system. However, this is purely arbitrary and any other system could be used as well. There is nothing intrinsic in the number twelve that would require us to write it as 12. The nice thing is that all arithmetic rules are defined on the numbers themselves, not on their representations. Five plus six will always be eleven. No matter how you represent them. You may have already noticed that I use number words when I talk about the numbers and any other representation if I talk about the representation.
Ok, so we have our numbers. Now we need a way to represent them. Imagine we have three symbols a, b, and c. We could just assign the first three numbers to them
a (zero)
b (one)
c (two)
But then we are out of symbols. As you know, the positional numeral systems solve this by introducing another position. Then, just continue as before. Assign the next few numbers in order
ba (three)
bb (four)
bc (five)
ca (six)
cb (seven)
cc (eight)
You might want to continue with a third position:
baa (nine)
bab (ten)
bac (eleven)
...
The base of this system is three (or ba) because we have three symbols. We can observe that the digits in the second position stand for an addition of a multiple of three (b. stands for three + ., c. stands for two times three + . ...) Expressed in base ba, this is: b. = b * ba + ., c. = c * ba + .. This continues to all positions and you can generalize that a number formed of digits dn ... d1 d0 can be expressed by the well-known formula:
n = Sum(i) di * base^i
The intuition behind this formula is that there will be base numbers with one digit, base^2 numbers with two digits and so on. And the di * base^i term skips the first few of them (as many such that the first digit matches, then the second and so on).
We can check this at the example of bac which should be eleven:
n = b * ba^c + a * ba^a + c * ba^a
= one * three^two + zero * three^one + two * three^zero
= nine + zero + two
= eleven
= bac
Remember that the arithmetic rules apply to the numbers and not to the representations? So since we know the definition of our number (second line in the above formula), we can use any other number representation. For example, the decimal one:
n = one * three^two + zero * three^one + two * three^zero
= 1 * 3^2 + 0*3^1 + 2*3^0
= 9 + 0 + 2
= 11 (decimal)
But we could also use another base, e.g. base-8:
n = one * three^two + zero * three^one + two * three^zero
= 1 * 3^2 + 0*3^1 + 2*3^0
= 11 + 0 + 2
= 13 (octal)
So basically, these systems arise naturally by assigning digit sequences systematically to subsequent numbers. The conversion is so simple because the positional equation applies to the numbers, not to the representations.
I hope this answer was not too abstract and helped you.
In R, I need to create a vector b = (1, 1+pi, 1+2pi, 1+3pi,...,1+19pi). I am unsure how to do this. I keep trying to use the seq command (i.e. seq(1, 1+npi n = 1:19) and that's totally wrong!), but don't know the proper syntax to make it work, thus it never does.
Any help would be appreciated.
R needs the multiplication operator.
b <- 1+ seq(0,19)*pi
Or slightly faster in situations where speed might matter:
b <- 1+ seq.int(0,19)*pi
You could use the equivalent:
b <- 1+ 0:19*pi
Because the ":" operator has very high precedence ( see ?Syntax), it's reasonable safe. Just be careful that you understand precedence when you use a minus or plus sign where it might be parse as a binary operator (remembering that spaces are ignored and that unary-minus has higher precedence than the single-colon, but binary minus or plus has a lower precedence :
> 1: 5+5
[1] 6 7 8 9 10
You should use simply 0:19 * pi + 1. Using seq is not so nice: seq(1, 1 + 19 * pi, by = pi) or seq(1, 1 + 19 * pi, length = 20).
If I enter a value, for example
1234567 ^ 98787878
into Wolfram Alpha it can provide me with a number of details. This includes decimal approximation, total length, last digits etc. How do you evaluate such large numbers? As I understand it a programming language would have to have a special data type in order to store the number, let alone add it to something else. While I can see how one might approach the addition of two very large numbers, I can't see how huge numbers are evaluated.
10^2 could be calculated through repeated addition. However a number such as the example above would require a gigantic loop. Could someone explain how such large numbers are evaluated? Also, how could someone create a custom large datatype to support large numbers in C# for example?
Well it's quite easy and you can have done it yourself
Number of digits can be obtained via logarithm:
since `A^B = 10 ^ (B * log(A, 10))`
we can compute (A = 1234567; B = 98787878) in our case that
`B * log(A, 10) = 98787878 * log(1234567, 10) = 601767807.4709646...`
integer part + 1 (601767807 + 1 = 601767808) is the number of digits
First, say, five, digits can be gotten via logarithm as well;
now we should analyze fractional part of the
B * log(A, 10) = 98787878 * log(1234567, 10) = 601767807.4709646...
f = 0.4709646...
first digits are 10^f (decimal point removed) = 29577...
Last, say, five, digits can be obtained as a corresponding remainder:
last five digits = A^B rem 10^5
A rem 10^5 = 1234567 rem 10^5 = 34567
A^B rem 10^5 = ((A rem 10^5)^B) rem 10^5 = (34567^98787878) rem 10^5 = 45009
last five digits are 45009
You may find BigInteger.ModPow (C#) very useful here
Finally
1234567^98787878 = 29577...45009 (601767808 digits)
There are usually libraries providing a bignum datatype for arbitrarily large integers (eg. mapping digits k*n...(k+1)*n-1, k=0..<some m depending on n and number magnitude> to a machine word of size n redefining arithmetic operations). for c#, you might be interested in BigInteger.
exponentiation can be recursively broken down:
pow(a,2*b) = pow(a,b) * pow(a,b);
pow(a,2*b+1) = pow(a,b) * pow(a,b) * a;
there also are number-theoretic results that have engenedered special algorithms to determine properties of large numbers without actually computing them (to be precise: their full decimal expansion).
To compute how many digits there are, one uses the following expression:
decimal_digits(n) = 1 + floor(log_10(n))
This gives:
decimal_digits(1234567^98787878) = 1 + floor(log_10(1234567^98787878))
= 1 + floor(98787878 * log_10(1234567))
= 1 + floor(98787878 * 6.0915146640862625)
= 1 + floor(601767807.4709647)
= 601767808
The trailing k digits are computed by doing exponentiation mod 10^k, which keeps the intermediate results from ever getting too large.
The approximation will be computed using a (software) floating-point implementation that effectively evaluates a^(98787878 log_a(1234567)) to some fixed precision for some number a that makes the arithmetic work out nicely (typically 2 or e or 10). This also avoids the need to actually work with millions of digits at any point.
There are many libraries for this and the capability is built-in in the case of python. You seem primarily concerned with the size of such numbers and the time it may take to do computations like the exponent in your example. So I'll explain a bit.
Representation
You might use an array to hold all the digits of large numbers. A more efficient way would be to use an array of 32 bit unsigned integers and store "32 bit chunks" of the large number. You can think of these chunks as individual digits in a number system with 2^32 distinct digits or characters. I used an array of bytes to do this on an 8-bit Atari800 back in the day.
Doing math
You can obviously add two such numbers by looping over all the digits and adding elements of one array to the other and keeping track of carries. Once you know how to add, you can write code to do "manual" multiplication by multiplying digits and putting the results in the right place and a lot of addition - but software will do all this fairly quickly. There are faster multiplication algorithms than the one you would use manually on paper as well. Paper multiplication is O(n^2) where other methods are O(n*log(n)). As for the exponent, you can of course multiply by the same number millions of times but each of those multiplications would be using the previously mentioned function for doing multiplication. There are faster ways to do exponentiation that require far fewer multiplies. For example you can compute x^16 by computing (((x^2)^2)^2)^2 which involves only 4 actual (large integer) multiplications.
In practice
It's fun and educational to try writing these functions yourself, but in practice you will want to use an existing library that has been optimized and verified.
I think a part of the answer is in the question itself :) To store these expressions, you can store the base (or mantissa), and exponent separately, like scientific notation goes. Extending to that, you cannot possibly evaluate the expression completely and store such large numbers, although, you can theoretically predict certain properties of the consequent expression. I will take you through each of the properties you talked about:
Decimal approximation: Can be calculated by evaluating simple log values.
Total number of digits for expression a^b, can be calculated by the formula
Digits = floor function (1 + Log10(a^b)), where floor function is the closest integer smaller than the number. For e.g. the number of digits in 10^5 is 6.
Last digits: These can be calculated by the virtue of the fact that the expression of linearly increasing exponents form a arithmetic progression. For e.g. at the units place; 7, 9, 3, 1 is repeated for exponents of 7^x. So, you can calculate that if x%4 is 0, the last digit is 1.
Can someone create a custom datatype for large numbers, I can't say, but I am sure, the number won't be evaluated and stored.
I want to make a short URL service for 2 million assets but I want to use the shortest number of possible characters.
What is the math equation that I would need to use to figure it out? I know it has something to do with factorials, right?
It's not a factorial problem, but an exponential one.
If x is the number of possible characters, you need to solve the following equation for y:
x^y = 2000000
If you want to use all numbers and case-sensitive alpha [0-9A-Za-z], you have 62 possible values. This means you need to solve:
62^y = 2000000
y*log(62) = log(2000000)
y = log(2000000) / log(62)
y = 3.5154313828...
Of course, you can't have 3.5 characters in your URL, so you would need 4. If you want to change the character set you are using for your URL's, simply resolve the problem above using the number of values in your set.
Note Solving this equation assumes fixed-length URL's. For variable-length URL's, see Rob's answer.
#jheddings is close, and got the right answer, but the math was not quite correct. Don't forget you are not limited to all the permutations of characters of a specific length. You can also leverage URLs of length 1 through y characters. Therefore we want the closed value of this sum:
x + x^2 + x^3 + ... + x^y = 2000000
Fortunately, there is a closed form for that sum:
x + x^2 + x^3 + ... + x^y = x*(x^y - 1)/(x-1) = 2000000
x is the number of possible characters in our range. For simplicity sake, let's assume it only includes lowercase, uppercase, and numbers (26+26+10 = 62.)
Then we get the following equation:
2000000 = (62^(y+1) - 62)/(62-1)
2000000 = (62^(y+1) - 62)/(61)
2000000 * 61 = 62^(y+1) - 62
122000000 = 62^(y+1) - 62
122000000 + 62 = 62^(y+1)
122000062 = 62^(y+1)
log(122000062) = (y+1)
log(122000062) / log(62) = y+1
4.511492 = y+1
3.511492 = y
And, as you said, 3.5 characters is impossible so 4 are required. Admittedly the difference doesn't matter in this case. However, in certain scenarios (especially when dealing with base 2) it is very important.
Number of possible short URLs = (Number of possible different characters in ID) raised to the power of (Length of ID in url)
For instance, if you're only using lowercase characters (of which there are 26) and your URLs look like http://domain.com/XXXXX (for your unique id's of 5 characters), then you can make 26^5 = 11,881,376 short urls.
If you were using upper and lower case letters, you'd have 52, so 52^5 = 380,204,032 possible short URLs, et cetera.
You need to answer a number of questions, like what kinds of characters you want to allow in your set.
All letters and all digits? base 36 (5 characters can fit 2mil+)
Distinguish between upper and lowercase? That gets you to base 62 (4 characters)
Remove easily-mistaken characters and numbers (e.g. i/l 0/o)? roughly base 32 (also 5 characters)
You can often solve this kind of problem without any math wizardry.
26+26+10 = 62 characters
Try 1. 62 = 62
Try 2. 62*62 = 3,844
Try 3. 62*62*62 = 238,328
Try 4. 62*62*62*62 = 14,776,336
So 4 is your answer :)
According to the HTTP/URI Spec you can additionally use the following "unreserved characters": ALPHA / DIGIT / "-" / "." / "_" / "~"
That adds an additional 4 characters to your radix and thus
Math.log(2000000) / Math.log(66) = 3.4629721616408813
Although this still means you will end up with a 4 character URL path at maximum.