javascript - How to increase the value of a number to the next multiple of 10, 100, 1000, 10,000 and so on - Stack Overflow

You'll have to forgive the phrasing of this question, I'm sure there's a better, more su

You'll have to forgive the phrasing of this question, I'm sure there's a better, more succinct way to ask it, but I don't know it.

Let's say I have a graph, and all the y-axis values are

[0,4,5,3,2,5,6]

The maximum value is six. So I would like the Y-Scale to be labeled from 0 to 10.

Given the following values

[33,26,54,23,86,23]

The maximum value is 86, so I would like the Y-Scale to go from 0 to 90.

Now let's say I have the following values

[98,253,87, 876,263]

The max is 876,so the Y-scale should go from 0 to 900

Now I have created the following function that should give me all the max y-scale values I need so far.

function padMaxValue(value){
        for(var i = 1; i < 1000000000000000000; i = i * 10){
            var decimalValue = value / i;

            if(value === i){
                return i;
            }

            if(decimalValue < 1 && decimalValue > 0.09){
                return i;
            }

        }
    }

However, given the following values

[99,123,82,189,45]

My function would set the y-scale max to 1000. But the max should really be 200. I realise that what I really need is a smarter way to increase the value of i instead of just multiplying it by 10. I need to be able to increase the value of i by 10, all the way up to 100. Then increase it by 100, all the way up to 1000. Then increase it by 1000, all the way up to 10,000 and so on.

I feel like there should be some neat and tidy mathematical way to do this. And I also feel that the 1000000000000000000 number I have in the for loop betrays my ignorance of mathematics.

Anyhoot, that's the problem. Any ideas?

You'll have to forgive the phrasing of this question, I'm sure there's a better, more succinct way to ask it, but I don't know it.

Let's say I have a graph, and all the y-axis values are

[0,4,5,3,2,5,6]

The maximum value is six. So I would like the Y-Scale to be labeled from 0 to 10.

Given the following values

[33,26,54,23,86,23]

The maximum value is 86, so I would like the Y-Scale to go from 0 to 90.

Now let's say I have the following values

[98,253,87, 876,263]

The max is 876,so the Y-scale should go from 0 to 900

Now I have created the following function that should give me all the max y-scale values I need so far.

function padMaxValue(value){
        for(var i = 1; i < 1000000000000000000; i = i * 10){
            var decimalValue = value / i;

            if(value === i){
                return i;
            }

            if(decimalValue < 1 && decimalValue > 0.09){
                return i;
            }

        }
    }

However, given the following values

[99,123,82,189,45]

My function would set the y-scale max to 1000. But the max should really be 200. I realise that what I really need is a smarter way to increase the value of i instead of just multiplying it by 10. I need to be able to increase the value of i by 10, all the way up to 100. Then increase it by 100, all the way up to 1000. Then increase it by 1000, all the way up to 10,000 and so on.

I feel like there should be some neat and tidy mathematical way to do this. And I also feel that the 1000000000000000000 number I have in the for loop betrays my ignorance of mathematics.

Anyhoot, that's the problem. Any ideas?

Share Improve this question edited Oct 31, 2014 at 10:48 gargantuan asked Oct 30, 2014 at 19:48 gargantuangargantuan 8,94616 gold badges69 silver badges110 bronze badges 7
  • You might consider two steps: 1. get min and max values of your data. 2. rounding them as you desire. – M. Page Commented Oct 30, 2014 at 19:54
  • 34 Why does 86 go to 100 not 90 if 876 goes to 900 not 1000? – curiousdannii Commented Oct 30, 2014 at 22:49
  • 4 good point. Just felt natural, humans are irrational. – gargantuan Commented Oct 30, 2014 at 22:56
  • 6 Do you want consistent rules or an exception for low values? Either way you should update your question to reflect your choice. All answers I have tested fails at your second test-case. – Hjulle Commented Oct 30, 2014 at 23:10
  • 4 The answers you have are good from an implementation/stackoverflow perspective, but you should probably also head over to the ux (User Experience) exchange to see if you really want to do this. My choice would be a small array of hand-picked, psychologically comforable, ux-driven values. This will be denser at the lower end of the scale than at the top end. You'd then pick the lowest of these, scaled by a power of 10, that can fit your data. – DeveloperInDevelopment Commented Oct 31, 2014 at 18:00
 |  Show 2 more comments

7 Answers 7

Reset to default 83

There is no need to go into the land of strings, which could be awkward if you ever had a decimal value.

function RoundedMax(a) {
    var mx = Math.max.apply(Math, a);
    if (mx == 0) {return 0};
    var size = Math.floor(Math.log(Math.abs(mx)) / Math.LN10);
    var magnitude = Math.pow(10, size);
    var yMax = Math.ceil(mx / magnitude) * magnitude;
    return yMax;
}

function RoundedMin(a) {
    var mn = Math.min.apply(Math, a);
    if (mn == 0) {return 0};
    var size = Math.floor(Math.log(Math.abs(mn)) / Math.LN10);
    var magnitude = Math.pow(10, size);
    var yMin = Math.floor(mn / magnitude) * magnitude;
    return yMin;
}

var arr = [-9.9,-1.23,-8.2,-2.01,-4.5,0];
document.write(RoundedMax(arr) + " " + RoundedMin(arr));

Outputs: 0 -10.

EDIT Updated in view of the comments. Now works even in IE8.


Now (2023) that all current browsers support ECMAScript 6:

function RoundedMax(a) {
    var mx = Math.max.apply(Math, a);
    if (mx == 0) {return 0};
    var size = Math.floor(Math.log10(Math.abs(mx)));
    var magnitude = Math.pow(10, size);
    var yMax = Math.ceil(mx / magnitude) * magnitude;
    return yMax;
}

function RoundedMin(a) {
    var mn = Math.min.apply(Math, a);
    if (mn == 0) {return 0};
    var size = Math.floor(Math.log10(Math.abs(mn)));
    var magnitude = Math.pow(10, size);
    var yMin = Math.floor(mn / magnitude) * magnitude;
    return yMin;
}

I don't like math, so here is a pretty simple/hilarious string-manipulation solution:

Find the maximum value:

var max = Math.max.apply(Math, [98,253,87, 876,263]); // 876

Take its first character

var c = max.toString()[0] // "8"

Make it an integer and add 1

c = (c | 0) + 1 // 9

Convert it back to a string:

c = c.toString() // "9"

Add N - 1 zeros to it, where N is the length of your original number:

c += Array(max.toString().length).join("0") // "900"

Convert it back to an integer:

c = (c | 0) // 900

Done!


Seriously though, use math.

I believe this would do the trick for you:

var data = [98, 253, 87, 876, 263, -155];
var max = Math.max.apply(null, data); // 
var factor = Math.pow(10, Math.floor(Math.log(Math.abs(max)) / Math.LN10)); 
if (factor == 0) { factor = 1; }                  
var magnitude = Math.ceil(max / (factor * 1.00)) * factor; 

Basically what's happening above is the following:

  1. Find the maximum of the sample
  2. Get the maximum values length, then raise it to a power of 10 i.e. 345, length = 3, so factor is 100
  3. Make sure we don't divide by 0
  4. Divide the maximum number by the factor to get a decimal, and take the ceiling of that number, then multiply it back by the factor to get the right number of 0s.

UPDATE: If you want to find the minimum value (for negative values), just flip the Math.ceil to Math.floor. You also have to take the absolute value of the minimum to make sure you don't count the negative character as part of the string.

var data = [98, 253, 87, 876, 263, -155];
var min = Math.min.apply(null, data);
var factor = Math.pow(10, Math.floor(Math.log(Math.abs(max)) / Math.LN10));
if (factor == 0) { factor = 1; }
var mag = Math.floor(min / (factor * 1.00)) * factor //  mag = -200;

UPDATE 2: As many people have said in the comments, we shouldn't be using string manipulation. I updated the code to use logarithms instead.

I wound up with:

function getGraphRange(data)
{
    var max=Math.max.apply(null, data);
    var min=Math.min.apply(null, data);
    var maxDigits=max.toString().length;
    var minDigits=min.toString().length;
    var maxD=Math.pow(10,Math.max((maxDigits-1),1));
    var minD=Math.pow(10,Math.max((minDigits-1),1));
    var maxR=(Math.ceil(max/maxD)*maxD);
    var minR=(Math.floor(min/minD)*minD);
    return [minR,maxR];
}
alert(getGraphRange([11, 20, 345, 99]).join(' - '));//10-400
alert(getGraphRange([0,4,5,3,2,5,6]).join(' - '));//0-10
alert(getGraphRange([98,253,87,876,263]).join(' - '));//80-900

http://jsfiddle.net/p4xjs9na/

There are already good answers here. I have used while loop to solve the problem. The function is very fast and it can return value in less than a second for even a very large number.

function padMaxValue(value)
{
    var i = 10;
    var counter = 0;
    var roundMax = 10;
    var copyValue = value;
    //If the value is negative, convert copyValue to positive
    if(value < 0) copyValue *= -1;
    while(roundMax <= copyValue)
    {
        roundMax += i;
        counter++;
        if(counter == 9)
        {
            i *= 10;
            counter = 0;
        }
    }
    if(value < 0) roundMax *= -1;
    return roundMax;
}
document.write(padMaxValue(8) + "<br>");
document.write(padMaxValue(77) + "<br>");
document.write(padMaxValue(889.65) + "<br>");
document.write(padMaxValue(-880.65) + "<br>");
document.write(padMaxValue(-765889.65) + "<br>");
document.write(padMaxValue(7888.88) + "<br>");
document.write(padMaxValue(88999887788899.099887) + "<br>");

Output:

10

80

900

-900

-800000

8000

90000000000000

I am not much of Math person but i take programming seriously! I came up with this solution!

function getMax(max){
    var mCopy = max;
    var d=1;//Assuming everything is greater than 10, 
    while(Math.floor(mCopy) > 10){//if the number is not one digited 
        mCopy /= Math.pow(10,d);
        d++;
    }
    d--;//back one digit
    if(d<1)
       d++;
    if((Math.floor(max / Math.pow(10,d))*Math.pow(10,d))==max)
       return max;
    return Math.floor(max / Math.pow(10,d))*Math.pow(10,d) + Math.pow(10,d);
}

Hope this helps

In my opinion the given answers are overly complicated. Here is an anonymous function that can be used in MATLAB:

next = @(x,n) ceil(x/n)*n;

>> next(11,10)    
ans =    
    20 %# 20 is the next "10" after "11")

>> next(110,100)    
ans =    
   200 %# 200 is the next "100" after "110"

>> next([98,253,87, 876,263],100)    
ans =    
   100   300   100   900   300

x is the number that should be processed and n is the requested step size.

edit Automation of determining the next order of magnitude is also possible

>> nextOrder = @(x) ceil(x/10.^ceil(log10(x))) * 10.^ceil(log10(x));

>> nextOrder([98,253,87,876,263])    
ans =    
         100        1000         100        1000        1000

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1737046063a3919776.html

相关推荐

  • StarRocks 存算分离在京东物流的落地实践

    康琪:京东物流高级技术专家、StarRocks & Apache Flink Contributor导读:本文整理自京东物流高级技术专家在 StarRocks 年度峰会上的分享,UData 平台从存算一体到存算分离架构演进后,查询性

    2小时前
    00
  • HarmonyOS NEXT条件语句和循环迭代

    条件语句使用规则支持if、else和else if语句。if、else if后跟随的条件语句可以使用状态变量或者常规变量(状态变量:值的改变可以实时渲染UI,常规变量:值的改变不会实时渲染UI)。允许在容器组件内使用,通过条件渲染语句构建不

    2小时前
    00
  • HarmonyOS NEXT数据类型和类

    数据类型```布尔类型let isDone: boolean = false;数字类型let decLiteral: number = 2023; 十进制let binaryLiteral: number = 0b1111110

    2小时前
    00
  • 鸿蒙开发:Canvas绘制之画笔对象Brush

    前言本文基于Api13在之前的文章中,我们主要针对Pen对象做了概述,知道了Pen对象主要用于修改绘制图形的轮廓信息,如果你想要实现一个实心的效果,那么就必须需要Brush对象了。我们还是拿着前边的案例代码做演示,使用Brush对象来实现一

    2小时前
    00
  • 【AI落地应用实战】大模型加速器2.0:基于 ChatDoc + TextIn ParseX+ACGE的RAG知识库问答系统

    一、私有知识库问答系统难点分析1.1、企业知识管理痛点分析在当今数字化浪潮席卷各行业的时代,企业内部信息管理的难题愈发凸显,构建高效的知识库已成为企业发展的必然选择。然而,企业知识管理中普遍存在着知识散落各处难以集中管理、信息孤岛现象严重部

    2小时前
    10
  • 必看!2025 年颠覆测试行业的 10 大 AI 自动化测试工具平台(上篇)

    大家好,我是狂师。上周小孩子生病,住院照顾,公众号停更了几天。各位看官,等着急了吧,之前有粉丝后台留言,想了解学习一下,AI这么火爆,那市面上AI与自动化测试结合起来的的工具平台有哪些值得学习的。今天就这个话题来聊一聊。前言在软件迭代以“

    2小时前
    10
  • 快升级!etcd官方v3.5.21版本深度解析,性能优化+兼容性全掌握

    开篇导语"3小时前,etcd社区刚刚发布了v3.5.21版本!作为云原生领域的核心存储组件,这次更新包含5768个 commits 的硬核优化。无论是开发者还是运维工程师,都需要关注这次升级的细节——本文将带你快速上手,揭秘新特性

    1小时前
    00
  • 实践教程|GPU 利用率低常见原因分析及优化

    仅用于学术分享,若侵权请联系删除一、GPU 利用率的定义本文的 GPU 利用率主要指 GPU 在时间片上的利用率,即通过 nvidia-smi 显示的 GPU-util 这个指标。统计方式为:在采样周期内,GPU 上面有 kernel 执行

    1小时前
    00
  • 4个AI提示词模板,帮你躺赢10万+爆文,第三个太狠了!

    一起 AI 创富想让你的内容在信息爆炸的时代脱颖而出?这4个精心设计的DeepSeeek AI 提示词模板将成为你的创作神器

    1小时前
    00
  • Java + LangChain 开发大语言模型应用!

    在 Baeldung 上看到了一篇介绍基于 Java + LangChain 开发大语言模型应用的基础入门文章,写的非常不错,非常适合初学者。于是,我抽空翻译了一下。1. 简介在本教程中,我们将详细探讨 LangChain[1],一个用于开

    1小时前
    00
  • C# 中的异步流与数据处理管道

    在当今世界,应用程序常常需要处理大量数据或进行实时更新。无论是股票价格的流式传输、日志处理,还是用户生成的内容,设计一个响应迅速且高效的数据管道都至关重要。借助 C# 的异步流和 IAsyncEnumerable,我们能够创建异步数据处理的

    1小时前
    00
  • 800G光模块:AI算力驱动的未来网络核心

    近年来,以ChatGPT为代表的AI大模型的快速崛起,使得全球对算力的需求呈现爆炸式增长。在AI算力集群中,800G光模块凭借更高的传输速率和更低的功耗,为大规模模型训练和推理任务提供高速低延迟的数据互联,成为未来算力网络不可或缺的核心组件

    56分钟前
    10
  • 正点原子DM40

    抱歉,最早还吐槽,狗都不买,嘿嘿当狗了:淘宝的图,我的还在路上鄙人是不和10V以上的电子系统打交道的,所以就是最低的版本了我就用用它的万用表功能,示波器太差了,信号发生器也差。想知道这东西的方案。器件倒是挺好看的这是拆了盖子的样子GD32的

    51分钟前
    10
  • 中台已死,十年再话

    中台作为中国互联网技术领域最玄幻的名词之一,曾经充斥在各种技术大会和公众号,面试高阶产品研发人才不探讨下中台都觉得差点儿意思。围绕中台诞生了无数热帖、无数架构图,各路大神现身说法布道授业解惑。你也说中台,我也说中台,仿佛万物皆可中台。各大出

    49分钟前
    00
  • 鸿蒙开发:Canvas绘制之画笔对象Pen

    前言本文基于Api13在上篇文章结尾,我们留了一个悬念,在使用DrawingRenderingContext对象进行绘制的时候,是无法更改画笔的粗细,颜色等属性的,如果你需要更改这些属性,必须借助其它对象来实现,如果是修改轮廓信息,可以使用

    39分钟前
    00
  • 手写数据库MYDB(一):项目启动效果展示和环境配置问题说明

    1.项目概况这个项目实际上就是一个轮子项目,现在我看到的这个市面上面比较火的就是这个首先RPC,好多的机构都在搞这个,还有这个消息队列之类的,但是这个是基于MYSQL的,我们知道这个MYSQL在八股盛宴里面是重点考察对象(就连我前段时间面试

    32分钟前
    00
  • AI 驱动自动化控制:从 “智” 造到 “慧” 控的跃迁

    AI 正驱动自动化控制领域变革,深度学习与机器学习宛如智慧引擎,重塑控制流程。从工业精准生产到智能交通高效调度,它们打破传统局限,实现从 “智” 造基础到 “慧” 控升级的关键一跃,为自动化领域开拓前所未有的创新发展路径 。一、背景自动化控

    27分钟前
    00
  • visio验证过期如何激活的问题解决方案

    1.问题的出现今天上午去完成学校的老师布置的实验报告的时候,打开visio出现了下面的这个提示:本来我并没有在意这个问题,但是我想要打开模版去完成作业的时候,发现这个是真的打不开啊,我才意识到看来这个软件是真的到期了,但是非常庆幸的是我在网

    22分钟前
    00
  • C++效率掌握之STL库:优先级队列priority

    本篇是 STL 库专题之 priority_queue 和 deque,书接上文1.priority_queuepriority_queue 的主要特征可总结为:优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元

    13分钟前
    00

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信