javascript fraction to percent - math

When I tried to convert fraction in Javascript, I am facing a problem.
I need to make a fraction value to percent value.
a = 0.0175
It should be displayed as 1.75%. I tried to multiply by 100. But I am getting some extra fractions added to the right - 1.7500000000000002 . I just need 1.75, not any more zeroes added to the end.
Thanks in advance.

Try this
var a = 0.0175
var num = a * 100;
var n = num.toFixed(2)

multiply, round and divide:
// rounding to set precision or default precision = 3
function roundToPrecision ( value, precision ) {
precision = ( typeof precision !== 'undefined' ) ? precision : 3;
var mult = Math.pow( 10, precision );
return Math.round( mult * value ) / mult;
}
usage:
var zzz = roundToPrecision( 123.1231232546 ); // 123.123
var aaa = roundToPrecision( 123.1231232546, 1 ); // 123.1

Try this:
function formatNum(n) {
return Math.round(n * 1e4) / 1e2;
}
var a = 0.0175;
var n = formatNum(a); // 1.75
var b = 0.21;
var m = formatNum(b); // 21
It simply multiplies by 100*100, rounds the result and divides again by 100. The result is still a number and not a string as with the toFixed-approach.

Related

Cannot read property 'add' of null

Hi all something wrong with my programming here as getting an error even though shape is drawn, but I can see it;s not quite right sketch
var circle= new Path.Circle({
radius: 100,
position: [200,200]
})
splat= new Path()
splat.fillColor= 'pink'
var count= 20
var length= circle.length
for(var i = 0; i <= count + 1; i++){
var offset= i / count * length
const normal = i === 0 || i === count
? new Point(0, 0)
: circle.getNormalAt(offset) * (Math.random() * 50);
const point = circle.getPointAt(offset).add(i % 2 == 0 ? normal
: -normal);
console.log(point)
splat.add(point)
splat.smooth({ type: 'catmull-rom', factor: 0.5 });
}
Thanks in advance
Your for loop stop condition is wrong:
i <= count + 1 should be either:
i < count + 1
i <= count
Otherwise when i is equal to count + 1, offset value is over length value and circle.getPointAt(offset) returns null.

How to group, sum, and average times in crossfilter.js

I am trying to find average time taken by the name. May i know the best way to find total time across all the name as well as the average time taken. Please find the details below
let data = [{"name":"A","children":"8:17:33"},{"name":"B","children":"9:30:45"},{"name":"C","children":"12:45:56"},{"name":"D","children":"4:20:30"},{"name":"E","children":"7:12:38"},{"name":"F","children":"6:29:45"},{"name":"G","children":"11:34:45"},{"name":"H","children":"10:30:45"},{"name":"I","children":"8:34:45"},{"name":"J","children":"8:34:12"}];
let CFX = crossfilter(data);
let dimName = CFX.dimension( (d)=> d.name);
let grpTime = dimName.group().reduceSum( (d)=> d.children);
console.log( grpTime.all() );
<script src="https://square.github.io/crossfilter/crossfilter.v1.min.js"></script>
EDIT: Here is a custom reduce to do it, but the resulting times come out as strings, and the average values are too large:
let data = [{"name":"A","children":"8:17:33"},{"name":"B","children":"9:30:45"},{"name":"C","children":"12:45:56"},{"name":"D","children":"4:20:30"},{"name":"E","children":"7:12:38"},{"name":"F","children":"6:29:45"},{"name":"G","children":"11:34:45"},{"name":"H","children":"10:30:45"},{"name":"I","children":"8:34:45"},{"name":"J","children":"8:34:12"}];
let CFX = crossfilter(data);
let dimName = CFX.dimension( (d)=> d.name);
let grpTime = dimName.group().reduceSum( (d)=> d.children);
//console.log( grpTime.all() );
let timeGrp = dimName.group().reduce(
function( p , v) {
p.count++;
let time = v.children.split(':');
p.time += time[0] * 60 * 60 + time[1] * 60 + time[2];
p.avg = p.time / p.count;
return p;
},
function( p , v) {
p.count--;
let time = v.children.split(':');
p.time -= time[0] * 60 * 60 + time[1] * 60 + time[2];
p.avg = p.count ? p.time / p.count : 0;
return p;
},
function( ) {
return {
time: 0,
avg: 0,
count : 0
}
}
);
console.log(timeGrp.all());
<script src="https://square.github.io/crossfilter/crossfilter.v1.min.js"></script>
One of the trickier things about JavaScript is that it will silently and happily convert strings to numbers, and vice versa, and it doesn't always do this correctly.
In this case, since your times are strings, and splitting those strings produces more strings, you've got a mix of strings and numbers.
But does JavaScript complain? No. It automatically converts strings to numbers, like
"8" * 60 = 480
But then it also converts numbers to strings, like
90 + "9" = 909
The right thing to do is convert those times to numbers immediately:
let time = v.children.split(':').map(x => +x);
let data = [{"name":"A","children":"8:17:33"},{"name":"B","children":"9:30:45"},{"name":"C","children":"12:45:56"},{"name":"D","children":"4:20:30"},{"name":"E","children":"7:12:38"},{"name":"F","children":"6:29:45"},{"name":"G","children":"11:34:45"},{"name":"H","children":"10:30:45"},{"name":"I","children":"8:34:45"},{"name":"J","children":"8:34:12"}];
let CFX = crossfilter(data);
let dimName = CFX.dimension( (d)=> d.name);
let grpTime = dimName.group().reduceSum( (d)=> d.children);
//console.log( grpTime.all() );
let timeGrp = dimName.group().reduce(
function( p , v) {
p.count++;
let time = v.children.split(':').map(x => +x);
p.time += time[0] * 60 * 60 + time[1] * 60 + time[2];
p.avg = p.time / p.count;
return p;
},
function( p , v) {
p.count--;
let time = v.children.split(':').map(x => +x)
p.time -= time[0] * 60 * 60 + time[1] * 60 + time[2];
p.avg = p.count ? p.time / p.count : 0;
return p;
},
function( ) {
return {
time: 0,
avg: 0,
count : 0
}
}
);
console.log(timeGrp.all());
<script src="https://square.github.io/crossfilter/crossfilter.v1.min.js"></script>

How do I sample isampler3d in webgl2?

two question. first off, how could I set a particular value in a 3d texture to 1, lets say the y coordinate of the element at index 1,1,1 in the following Int16Array so I could later read it. I think it'd go something like this:
var data = new Int16Array(size * size * size);
data.fill(0);
// ??? (somehow I'd set values of the data array at index 1,1,1 but I'm unsure how)
data ??? = 1;
gl.texImage3D(
gl.TEXTURE_3D,
0,
gl.R16I,
size,
size,
size,
0,
gl.RED_INTEGER,
gl.SHORT,
data);
secondly, later in my fragment shader, how could I grab that value using the GLSL texture function. I think it'd go something like this:
uniform isampler3d t_sampler;
...
ivec4 value = texture( t_sampler , vec3( 1.0 , 1.0 , 1.0 ) );
if( value.y == 1 ){
// do some special stuff
}
any help would be appreciated. again I'm just trying to create my texture using a data array I create and then read that value in the frag shader.
fyi this code is running but failing to get to the "do some special stuff" part.
thanks
// ??? (somehow I'd set values of the data array at index 1,1,1 but I'm unsure how)
data ??? = 1;
const width = ??
const height = ??
const depth = ??
const numChannels = 1; // 1 for RED, 2 for RG, 3 for RGB, 4 for RGBA
const sliceSize = width * height * numChannels;
const rowSize = width * numChannels;
const x = 1;
const y = 1;
const z = 1;
const offset = z * sliceSize + y * rowSize + x;
data[offset] = redValue;
If there are more channels, for example RGBA then
data[offset + 0] = redValue;
data[offset + 1] = greenValue;
data[offset + 2] = blueValue;
data[offset + 3] = alphaValue;
how could I grab that value using the GLSL texture function
To get a specific value from a texture you can use texelFetch with pixel/texel coordinates.
uniform isampler3d t_sampler;
...
int x = 1;
int y = 1;
int z = 1;
int mipLevel = 0;
ivec4 value = texelFetch(t_sampler, ivec3(x, y, z), mipLevel);
if( value.y == 1 ){
// do some special stuff
}
Be sure to check the JavaScript console for errors. In your case you probably need to set filtering to NEAREST since you're not providing mips and since integer textures can not be filtered.

How to create different iterations of 6 digit integer that is also 6 digits?

I am using an algorithm to create a 6 digit pin from a string of letters(I already have it). I also need to make different iterations of this 6 digit pin that would all lead back to the origin pin which can be used to generate the string of letters.
input "FEFOEISUDFRORI"
output 523923
some algorithm...
first iteration: 123203
then to authenticate
iteration: 1 ; pin: 123203
output: 'FEFOEISUDFRORI' // same as original string
Any idea how to do this?
The easiest way to solve this mathematical problem is probably with a rotation. Essentially performing an addition then a modulus, rotation will result in a one-to-one function with a range equal to it's domain.
The example I've shown will rotate the entire 6 digit number or the individual digits of the number.
function rRot(x, rot, max) {
if (rot < 0) return lRot(x,-rot,max);
rot = rot % max;
return (x + rot) % max;
}
function lRot(x, rot, max) {
if (rot < 0) return rRot(x,-rot,max);
rot = rot % max;
return rRot(x,max-rot,max);
}
function rotDigits(x, r) {
var pwr = 1, y = 0;
while (x > 0) {
var digit = x % 10;
y += rRot(digit, r, 10) * pwr;
x = Math.floor(x / 10);
pwr *= 10;
}
return y;
}
var samples = [675821, 126421, 678321, 100001, 580127, 999999];
(function () {
console.log("Rotate individual digits");
samples.forEach(v => {
var r = rotDigits(v, 7);
var vr = rotDigits(r, 10-7);
console.log(v.toString() + " => " + r.toString() + " => " + vr.toString());
});
console.log("Rotate whole number");
samples.forEach(v => {
var r = rRot(v, 65537, 1000000);
var vr = lRot(r, 65537, 1000000);
console.log(v.toString() + " => " + r.toString() + " => " + vr.toString());
});
})()

How to increase a number for a certain percentage (say %10) expotential number of times (say 20) and then decrease it to base value again?

I basically have a number, say 100.
I can increase it by 10 percent every time. So, :
1st run it would become 110,
2nd 121,
3rd 133 and so on.
I can have count of how much the value was increased. But how to expotentialy decrease the amount knowing the number of times it has been increased back to 100?
Is there a way to do it with simple math op like ** instead of looping the current value amount of times it has been altered by 10 percents?
I know I can just store it in additionl column like base_number=100 or something when I need the basic value, but I would like to know if its possible to do by one-liner calculations?
So your basic question is, how do you invert and find x_0 given a known n and:
x_n = x_0 * 1.1^n
Looks like we can simply divide through by 1.1^n
x_n/(1.1^n) = x_0
So you can either calculate 1.1^n with pow(1.1, n) and divide x_n (your "increased" value) by that, or just loop and reduce like you increased:
//1.
$original = $increased/pow(1.1, n);
//2.
$original = $increased;
for ($i = 0; $i < n; $i++) {
$original = $original / 1.1;
}
So in your example, let's say our $increased is known to be 133, and n=3. Then using the first method:
$original = 133 / (1.1^3) = 133 / 1.33 = 100
Let's make a simple example and try to find a formula :
100 * 1.10 = 110;
110 * 1.10 = 121;
121 * 1.10 = 133.1;
So right now we have :
basic_number (will be bn) * increase_value (will be iv) = basic_number2;
bn2 * iv = bn3;
bn3 * iv = bn4;
We can write it too :
bn * iv = bn2;
bn * iv * iv = bn3;
bn * iv * iv * iv = bn4;
And so we have the beginning of a formula :
bn * iv^3 = bn4;
Now what you will have as data according to your post is :
X : the number of increase
bnX : the basic number increase X time
iv : the increase value
And you want to find bn according to those value :
bn * iv^X = bnX;
bn = bnX / iv^X;
bn = bnX / (iv * iv * iv ... * iv); // X time
So with PHP it could look like this :
$X = /* the number of incease */;
$bnX = /* the basic number increase X time */;
$iv = /* the increase value */;
for($i = 0; $i < $X; $i++) {
$bnX = $bnX / $iv;
}
This way you will if you echo $bnX; at the end of the loop, you should get your basic number !
You can try to make a php formula to do it and use it every time :
// 1/ Using a loop
function getBasicNumber($bnX, $X, $iv) {
for($i = 0; $i < $X; $i++) {
$bnX = $bnX / $iv;
}
return $bnX;
}
EDIT
// 2/ Using pow
function getBasicNumber($bnX, $X, $iv) {
return $bnX / pow($X, $iv);
}
// 3/ Using '**'
function getBasicNumber($bnX, $X, $iv) {
return $bnX / $X**$iv;
}
This way you just have to do :
echo getBasicNumber(133.1, 3, 1.10); // 100 here for example
Hope it's clear? But still, it's more a maths problem than a programming one

Resources