Как улучшить мою функцию, которая округляет число с плавающей точкой до ближайшего 10, если 2-значный номер, 100, если 3-значный номер и т. Д - PullRequest
0 голосов
/ 11 декабря 2018

Я рисую гистограммы и столкнулся с непростой проблемой.Как программно установить максимальное значение для метки оси Y в зависимости от максимального значения для данной серии.Так что, если у вас есть столбец со значением 7, вы можете захотеть, чтобы ось y поднялась до 10

Мой подход не идеален, но работает так:

  • Получитьчисло к округлению, например 829
  • Подсчет количества цифр (3)
  • Использование цикла для преобразования в строку 0 с ("000")
  • Добавление 1в начало строки, затем преобразовать в число с плавающей точкой (1000)
  • Найти разницу (1000 - 829 = 171)
  • Получить первую цифру разницы (1) и затем добавить, чтов первую цифру числа с плавающей запятой, с остальными установленными в ноль ("900"), затем преобразуйте в число (900)

Это означает, что 725 увидит максимальный номер метки оси Y, равный 800и 829 из 900

Мой код работает, но я чувствую, что это кусок дерьма с хакерским подходом

Мне нужно кодировать для больших чисел.Например, если значение с плавающей точкой, для которого я хочу найти максимальное значение, составляет> 10000, то возьмите первые две цифры и добавьте к нему 1000.Если> 100 000, добавьте 10 000

Как я могу улучшить ситуацию здесь?Я немного застрял, моя идея преобразования строк даже правильно?!

Полный код здесь:

package main

import (
    "fmt"
    "strconv"
)

func main() {

    myFloat := 899175.0

    x := getMaxYAxisValueForChart(myFloat)
    fmt.Println("The number to find the maximum value for is: ", myFloat)
    fmt.Println("This should be the max value for the y axis: ", x)
}

func getMaxYAxisValueForChart(float float64) (YAxisMaximum float64) {
    //Convert to string with no decimals
    floatAsString := fmt.Sprintf("%.f", float)

    //Get length of the string float
    floatAsStringLength := len(floatAsString)

    //For each digit in the string, make a zero-string
    stringPowerTen := "0"
    for i := 1; i < floatAsStringLength; i++ {
        stringPowerTen += "0"
    }

    //Add a 1 to the 0 string to get the difference from the float
    stringPowerTenWithOne := "1" + stringPowerTen

    //Convert the number string to a float
    convertStringPowerTenToFloat := ConvertStringsToFloat(stringPowerTenWithOne)

    //Get the difference from the denominator from the numerator
    difference := convertStringPowerTenToFloat - float

    //We want to isolate the first digit to check how far the float is (100 is far from 1000) and then correct if so
    floatAsStringDifference := fmt.Sprintf("%.f", difference)
    runes := []rune(floatAsStringDifference)
    floatAsStringDifferenceFirstDigit := string(runes[0])

    //For the denominator we want to take away the difference that is rounded to the nearest ten, hundred etc
    runes = []rune(stringPowerTen)
    differenceLastDigitsAsString := ""
    if difference < 10 {
        differenceLastDigitsAsString = "1"
    } else if difference < 30 && difference < 100 {
        differenceLastDigitsAsString = "0"
    } else {
        differenceLastDigitsAsString = floatAsStringDifferenceFirstDigit + string(runes[1:])
    }

    //Convert the number difference string from total to a float
    convertDifferenceStringPowerTenToFloat := ConvertStringsToFloat(differenceLastDigitsAsString)

    YAxisMaximum = convertStringPowerTenToFloat - convertDifferenceStringPowerTenToFloat

    //If float is less than 10,0000
    if float < 10000 && (YAxisMaximum-float >= 500) {
        YAxisMaximum = YAxisMaximum - 500
    }

    if float < 10000 && (YAxisMaximum-float < 500) {
        YAxisMaximum = YAxisMaximum
    }

    //If number bigger than 10,000 then get the nearest 1,000
    if float > 10000 {

        runes = []rune(floatAsString)
        floatAsString = string(runes[0:2])
        runes = []rune(stringPowerTen)
        stringPowerTen = string(runes[2:])
        runes = []rune(stringPowerTenWithOne)
        stringPowerTenWithOne = string(runes[0:(len(stringPowerTenWithOne) - 2)])

        YAxisMaximum = ConvertStringsToFloat(floatAsString+stringPowerTen) + ConvertStringsToFloat(stringPowerTenWithOne)
    }

    if float > 10000 {

        runes = []rune(floatAsString)
        floatAsString = string(runes[0:2])
        runes = []rune(stringPowerTen)
        stringPowerTen = string(runes[:])
        runes = []rune(stringPowerTenWithOne)
        stringPowerTenWithOne = string(runes[0:(len(stringPowerTenWithOne))])

        YAxisMaximum = ConvertStringsToFloat(floatAsString+stringPowerTen) + ConvertStringsToFloat(stringPowerTenWithOne)
    }

    return YAxisMaximum
}

func ConvertStringsToFloat(stringToConvert string) (floatOutput float64) {
    floatOutput, Error := strconv.ParseFloat(stringToConvert, 64)
    if Error != nil {
        fmt.Println(Error)
    }

    return floatOutput
}

Вот решениеоснованный на ответе Мэтта Тиммерманса, но преобразованный для работы в Go:

func testing(float float64) (YAxisMaximum float64) {
    place := 1.0
    for float >= place*10.0 {
        place *= 10.0
    }
    return math.Ceil(float/place) * place
}

Ответы [ 4 ]

0 голосов
/ 12 декабря 2018

Поскольку 829 является целым или может быть приведено к чистому целочисленному решению:

func getMaxYAxisValueForChart(int int64) {
    base := 10;
    while int > base*10 {
        base := 10 * base; 
    }
    return int + (base - int) % base;
}
0 голосов
/ 11 декабря 2018

Возьмите длину строки и вычислите, что 10 к степени этой длины

Или ... лучше возьмите основание Log 10, получите целую часть, добавьте 1 и затем верните это в степеньиз 10:)

    import (
        "fmt"
        "math"
    )

    //func PowerScale(x int) int64{
    //   return int64(math.Pow(10,float64(len((fmt.Sprintf("%d",x))))))
    //}

    func PowerScale(x int) int64 {
     return int64(math.Pow(10,float64(int(math.Log10(float64(x))+1))))
}

    func main() {
        fmt.Println(PowerScale(829))
        fmt.Println(PowerScale(7))
    }
0 голосов
/ 11 декабря 2018

Вы можете получить величину числа, используя Math.Log10

int magnitude = (int)Math.Pow(10, (int)Math.Log10(value));

. Используйте это, чтобы разделить число вниз, вычислить потолок и затем увеличить его.

Без строк, без циклов.

0 голосов
/ 11 декабря 2018

Ух ты, это довольно сложная процедура.Вот как бы я это сделал, если бы цифры не были огромными.Я не знаю, иди, поэтому я буду догадываться о том, как написать это на этом языке:

func getMaxYAxisValueForChart(float float64) {

    place := 1.0;
    while float >= place*10.0 {
        place *= 10.0;
    }
    return math.Ceil(float/place) * place;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...