Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 16th July 2022, 19:39   #1  |  Link
anton_foy
Registered User
 
Join Date: Dec 2005
Location: Sweden
Posts: 703
Make 1 decimal on float

Here I have a part of my script but I get 6 decimals (e.g. 1.123456) and I only want 1 (e.g. 1.1). Is this possible somehow?

Code:
in = levels(6*256,1,122*256,0,255*256)

    t=ScriptClip(function[in] () {

        nTH  = in.YDifferenceToNext()
        s  = float(nTH*0.00009)

Subtitle("Noise=" + String(s), align=2)
    } )
t
anton_foy is offline   Reply With Quote
Old 16th July 2022, 20:09   #2  |  Link
Julek
Registered User
 
Julek's Avatar
 
Join Date: Dec 2020
Posts: 88
Code:
flt1 = 1.123456

int1 = Floor(flt1*10) #or Round(flt1*10)
flt2 = Float(int1)/10 #= 1.1000000
__________________
CPU: AMD 3700X | GPU: RTX 3070Ti | RAM: 32GB 3200MHz
GitHub

Last edited by Julek; 16th July 2022 at 20:14.
Julek is offline   Reply With Quote
Old 16th July 2022, 20:38   #3  |  Link
Dogway
Registered User
 
Join Date: Nov 2009
Posts: 2,361
You can use String() to format to one decimal with rounding.
I made a wrapper for that: nmod(num, dec=1)

I see you directly want it for subtitle, so just use straight String()
Subtitle("Noise=" + String(s,"%0.1f"), align=2)
__________________
i7-4790K@Stock::GTX 1070] AviSynth+ filters and mods on GitHub + Discussion thread
Dogway is offline   Reply With Quote
Old 16th July 2022, 20:56   #4  |  Link
anton_foy
Registered User
 
Join Date: Dec 2005
Location: Sweden
Posts: 703
Thank you both!

@Julek
I get without any decimal (in this case: 2) when trying
Code:
s = floor(nth*0.00009)
And with this
Code:
s = float(nth)/10009
I get: 2.315716

@Dogway
Great in which package can I find this wrapper function? Actually I need this for TemporalDegrain2 to dynamically adjust postSigma, in this example I just wanted to see the result shown as a string.

EDIT: Now I tried this:
Code:
s = nmod(nTH*0.00009, dec=1)
but it gives me: 2.100000.
Maybe this is fine to feed to postsigma?

Last edited by anton_foy; 16th July 2022 at 21:00.
anton_foy is offline   Reply With Quote
Old 17th July 2022, 10:34   #5  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 4,829
If you always want one decimal place, use Dogway's suggestion and set it with the string() function, but for possible future use, here's a function for formatting numerical strings. The original idea was for the function to remove unnecessary trailing zeros, so as a result you can set the maximum number of decimal places, but it's only a maximum. I don't know if using a function like this inside ScriptClip would slow it down much.

The Limit argument sets the maximum number of decimal places (up to 6). Limit=3 is the default, but that's easy to change if you wish.
Keep=true is for when you always want at least one decimal place, so it ensures a zero after the decimal point is kept or it's added if necessary (unless Limit=0).
The TextA and TextB arguments allow the insertion of text before and after the number being converted to a string, as you'd normally be able to do with the string() function.
The function also removes any negative sign from zero, so -0.0 would display as 0.0

Format String.avsi

Some examples.
Code:
A = 72.00667
FormatStr(A)                     # 72.007
FormatStr(A, limit=2)            # 72.01
FormatStr(A, limit=1)            # 72
FormatStr(A, limit=1, keep=true) # 72.0

A = 1.00004
string(A, "%.6f")                # 1.000040
FormatStr(A, limit=6)            # 1.00004
string(A, "%.4f")                # 1.0000
FormatStr(A, limit=4)            # 1
FormatStr(A, limit=4, keep=true) # 1.0

A = -0.0005
string(A, "%.2f")                # -0.00
FormatStr(A, limit=2)            # 0
FormatStr(A, limit=2, keep=true) # 0.0

A = 1280.0
B = 720.0
# Displays - Resolution: 1280 x 720
subtitle(string(A, "Resolution: %.0f x ") + string(B, "%.0f"))

# Displays - Resolution: 1280.00 x 720.00
subtitle(string(A, "Resolution: %.2f") + string(B, " x %.2f"))

# Displays - Resolution: 1280 x 720
subtitle(FormatStr(A, "Resolution: ", " x ") + FormatStr(B))

# Displays - Resolution: 1280.0 x 720.0
subtitle(FormatStr(A, "Resolution: ", Keep=true) + FormatStr(B, " x ", Keep=true))

Last edited by hello_hello; 18th July 2022 at 10:46.
hello_hello is offline   Reply With Quote
Old 17th July 2022, 14:56   #6  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
This (StrFmt) was a "special", ripped out of RT_Stats whosit [In RT_stats named RT_String() ].

@MediaFire below this post. [StrFmt_25&26_x86_x64_dll_v1.00_20190114.zip, 72KB, incl 3 * dll + source + VS2008 Project files]
Or Here:- https://www.mediafire.com/file/nhu73...90114.zip/file

Code:
StrFmt(String format, dat1,...,datn)

 dll's for avs v2.58 & v2.60 x86 & x64.

 Returns a formatted string. The unnamed 'format' string and optional unnamed 'dat' args are used to construct the text string that is
 returned, uses C/CPP printf() style formatting.
 Format: compulsory string controlling format and describing the datn type args that are expected.
 datn: Variable number of data args of any type (excluding clip).

 printf Format spec here:- http://msdn.microsoft.com/en-us/library/56e442dc%28v=vs.71%29.aspx    # M$ Link Now BAD
  NOTE, the only support for printing Bool variables is %s as string, ie prints "True" or "False".

 Formatting supported, %[flags] [width] [.precision] type

  flags, one of  "-,+,0, ,#"
  width, integer, "*" supported (width supplied via dat arg).
  Precision, integer, "*" supported (precision supplied via dat arg).
  type,
    "c,C,d,i,o,u,x,X",  Integer type, c,C=character, d,i=signed, o,u,x,X=unsigned (o=octal, x=Hex).
    "e,E,f,g,G",        Floating point type
    "s,S",              String type (also Bool).

  Formatting Insertion point is marked with '%' character in the format string (as in Avisynth String function), if you wish to use
  a percent character within the returned string, it should be inserted twice in the format string ie '%%' will produce a single '%'.
  The data datn arg strings do not require a double '%' character.

  A Backslash character '\' introduces escape sequences, to insert a backslash character itself, you must supply a double
  backslash sequence ie '\\'.
  Converts embedded escape character sequences (Case Significant):-
    '\\' Converted to '\'       Single Backslash
    '\n' Converted to Chr(10)   NewLine
    '\r' Converted to Chr(13)   Carriage Return
    '\t' Converted to Chr(9)    Horizontal TAB
    '\v' Converted to Chr(11)   Vertical TAB
    '\f' Converted to Chr(12)   FormFeed
    '\b' Converted to Chr(8)    BackSpace
    '\a' Converted to Chr(7)    Bell
    '\x', where x is ANY OTHER CHARACTER not included above, will be copied verbatim, ie '\x'.

  eg
   StrFmt("Hello there %s and %s.\nGoodbye %d.","Fred","Ted",2019)
   would return same as:-   "Hello there Fred and Ted." + Chr(10) + "Goodbye 2019."

*****
*****
*****

StrRep(string source,string find,string replace,bool "sig"=True)   # Based on Algorithm by Vampiredom, Gavino & IanB.

 String args 'source', 'find' and 'replace' unnamed and compulsory.
 Takes a source string, searches for all occurences of find string and replaces the found strings with the replace string.
 Can use "" in replace string (only in replace) to delete the found substrings from the source string.
 Newlines [Chr(10)] are treated no differently to other characters, and could be replaced/deleted.
 'sig' arg,default true is Case Significant. Set false for case insignificant find string.
Quote:
I only want 1 (e.g. 1.1).
So something like
Code:
Subtitle(StrFmt("Noise=%.1f",nTh), align=2)
EDIT: Advanced. [Width and Precision, can be supplied as variable args instead of embedded in format string]
Code:
colorbars.killaudio
S = StrFmt("'%0*.*f'",10,3,9999.99)
Subtitle(S) # print '009999.990', ie minimum total length of digits and '.' is 10, with 3 fractional digits. 
# RED Asterisk, is replaced with 1st arg '10', BLUE Asterisk is replacedwith 2nd arg '3', actual number to convert is 9999.99.
# The "%0" before minimum total length of digits, means 'pad with leading zeros' (otherwise pad with spaces).
# A "%-" instead of above "%0" would left align the result, space padding on right {in this case padding to 10 characters by the Red asterisk 10 arg}.
EDIT: The given MicroSoft C Printf spec page is broken, so here some others.

https://docs.microsoft.com/en-us/cpp...?view=msvc-170
https://www.freecodecamp.org/news/fo...ecifiers-in-c/
https://cplusplus.com/reference/cstdio/printf/

Quote:
NOTE, the only support for printing Bool variables is %s as string, ie prints "True" or "False".
But can use eg Subtitle(StrFmt("Bool=%.1s",True)) # produces "Bool=T".

EDIT: StrFmt thread:- https://forum.doom9.org/showthread.php?t=174649
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 17th July 2022 at 20:20.
StainlessS is offline   Reply With Quote
Old 17th July 2022, 22:06   #7  |  Link
anton_foy
Registered User
 
Join Date: Dec 2005
Location: Sweden
Posts: 703
This is great stuff thanks guys! So if I get this correctly I can convert to String and remove the excessive zeroes and then back to float to feed to for example FFT3D's sigma?
anton_foy is offline   Reply With Quote
Old 18th July 2022, 04:47   #8  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
back to float to feed to for example
yes, maybe this shows use.

Code:
MyName = "TEST: "
F = Pi

RT_DebugF("Pi = %s\n",String(F),name=MyName)

For(i=0,6) {
    S = FracRoundAsString(F,i)
    N = Eval(S)
    RT_DebugF("%d] N=%f S='%s'", i, N, S,name=MyName)
}

Return MessageClip("DONE")

Function FracRoundAsString(Float Num,Int "FracDigits") {
    FracDigits = Default(FracDigits,1).Max(0)  # Int, at least 0
    Return StrFmt("%1.*f",FracDigits,Num)
}

# DebugView Result
Code:
00000481	0.19399980	TEST: Pi = 3.141593
00000482	0.19410621	TEST:
00000483	0.19422890	TEST: 0] N=3.000000 S='3'               # but NOTE here, Eval("3") would result in N = int value 3 [but we have printed N as a float].
00000484	0.19432700	TEST: 1] N=3.100000 S='3.1'
00000485	0.19441921	TEST: 2] N=3.140000 S='3.14'
00000486	0.19451070	TEST: 3] N=3.142000 S='3.142'
00000487	0.19462951	TEST: 4] N=3.141600 S='3.1416'
00000488	0.19472340	TEST: 5] N=3.141590 S='3.14159'
00000489	0.19480871	TEST: 6] N=3.141593 S='3.141593'
EDIT: I've printed N before S as N has constant length so as to maintain formatting.

EDIT: Renamed FracRound() to FracRoundAsString()
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 18th July 2022 at 05:20.
StainlessS is offline   Reply With Quote
Old 18th July 2022, 10:34   #9  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 4,829
anton_foy,
for TemporalDegrain2 it won't matter how many decimal places the value has as long as it accepts float.
If you want to round to a single decimal place anyway, why not use Julek's method?

flt1 = 1.123456

int1 = floor(flt1*10.0) # rounds down to 11
or
int1 = ceil(flt1*10.0) # rounds up to 12
or
int1 = round(flt1*10.0) # rounds to nearest integer so 11

flt2 = int1/10.0 = 1.1000000 (or 1.2000000)

subtitle(string(flt2, "%.1f")) # displays 1.1 (or 1.2)
hello_hello is offline   Reply With Quote
Old 18th July 2022, 13:34   #10  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Julek/Hello*2, fine if always fixed number of fractional digits.
But alternative,

Code:
MyName = "TEST2: "
F = Pi

RT_DebugF("Pi = %s\n",String(F),name=MyName)

For(i=0,6) {
    Fact = Pow(10,i)
    N    = Round(F*Fact) / Fact
    Fmt  = "%1."+String(i)+"f"
    S    = String(N,Fmt)
    RT_DebugF("%d] Fact=%9.1f : Fmt='%s' : N=%f : S='%s'", i, Fact,Fmt, N, S, name=MyName)
}

Return MessageClip("DONE")


__END__


00001043    0.17602471  TEST2: Pi = 3.141593
00001044    0.17610569  TEST2:
00001045    0.17620590  TEST2: 0] Fact=      1.0 : Fmt='%1.0f' : N=3.000000 : S='3'
00001046    0.17626271  TEST2: 1] Fact=     10.0 : Fmt='%1.1f' : N=3.100000 : S='3.1'
00001047    0.17632370  TEST2: 2] Fact=    100.0 : Fmt='%1.2f' : N=3.140000 : S='3.14'
00001048    0.17634501  TEST2: 3] Fact=   1000.0 : Fmt='%1.3f' : N=3.142000 : S='3.142'
00001049    0.17641900  TEST2: 4] Fact=  10000.0 : Fmt='%1.4f' : N=3.141600 : S='3.1416'
00001050    0.17647520  TEST2: 5] Fact= 100000.0 : Fmt='%1.5f' : N=3.141590 : S='3.14159'
00001051    0.17648339  TEST2: 6] Fact=1000000.0 : Fmt='%1.6f' : N=3.141593 : S='3.141593'
EDIT: And in actual use you dont need RT_DebugF() or StrFmt(), and Fact and Fmt can be pre-calculated outside of any eg Scriptclip.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 18th July 2022 at 13:50.
StainlessS is offline   Reply With Quote
Old 18th July 2022, 15:19   #11  |  Link
anton_foy
Registered User
 
Join Date: Dec 2005
Location: Sweden
Posts: 703
Quote:
Originally Posted by hello_hello View Post
anton_foy,
for TemporalDegrain2 it won't matter how many decimal places the value has as long as it accepts float.
If you want to round to a single decimal place anyway, why not use Julek's method?

flt1 = 1.123456

int1 = floor(flt1*10.0) # rounds down to 11
or
int1 = ceil(flt1*10.0) # rounds up to 12
or
int1 = round(flt1*10.0) # rounds to nearest integer so 11

flt2 = int1/10.0 = 1.1000000 (or 1.2000000)

subtitle(string(flt2, "%.1f")) # displays 1.1 (or 1.2)
Thank you well I learn something new all the time. I was under the inpression that it would slow down when many decimals but apparently not, good news!
anton_foy is offline   Reply With Quote
Old 18th July 2022, 16:30   #12  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 4,829
Quote:
Originally Posted by anton_foy View Post
Thank you well I learn something new all the time. I was under the inpression that it would slow down when many decimals but apparently not, good news!
As far as I know floating point has a fixed number of digits, even if it's mostly zeros.
https://en.wikipedia.org/wiki/Floati...-point_numbers
So even if you converted a string with a single decimal place to float it'd still have lots of zeros, it's just that by default you only see six of them with string().

For the record, not all numbers can be represented exactly in 32 bit floating point anyway, and is probably one reason why the string function defaults to rounding to 6 decimal places.
One of the examples I used in my first post, 72.00667, converts to this in float.

subtitle(string(72.00667, "%.20f"))



or a smaller number such as 1.55
subtitle(string(1.55))



subtitle(string(1.55, "%.24f"))



0.00009 from your script
subtitle(string(0.00009, "%.40f"))


Last edited by hello_hello; 18th July 2022 at 16:49.
hello_hello is offline   Reply With Quote
Old 25th July 2022, 20:41   #13  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 4,829
I don't know if anyone was interested in the function I linked to in post #5, but I was playing around with the concept of recursion today and it occurred to me it could be applied to removing trailing zeros for the Format String function, so here's a far less "wordy" version that does exactly the same thing, but without a limitation on the maximum number of decimal places, aside from whatever the maximum is for String().

Code:
# ===============================================================================
#            Format String
# ===============================================================================

function FormatStr(float F, string "Text1", string "Text2", int "Limit", bool "Keep", int "Width") {

Text1 = default(Text1, "")
Text2 = default(Text2, "")
Limit = abs(default(Limit, 3))
Keep = default(Keep, false)
Width = abs(default(Width, 0))
WidthStr = (Width > 0) ? string(Width) : ""

S = Eval("""string(F, "%""" + WidthStr + "." + string(Limit) + """f")""")
S = (Limit == 0) ? S : RemoveTrailingZeros(S)
SLength = StrLen(S)
NewStr = (Limit == 0) || (FindStr(S, ".") < SLength) ? S : !Keep ? LeftStr(S, SLength - 1) : S + "0"
NewStr = (value(NewStr) == 0) && (FindStr(NewStr, "-") > 0) ? RightStr(NewStr, StrLen(NewStr) - 1) : NewStr

return Text1 + NewStr + Text2 }

function RemoveTrailingZeros(string S) {
ZeroPos = FindStr(S + "x", "0x")
return (ZeroPos == 0) ? S : RemoveTrailingZeros(LeftStr(S, ZeroPos - 1)) }

# ===============================================================================
Edit: Inspired by one of StainlessS's functions above, I added a "Width" argument, then tried to work out how it might be useful, at least for me. To line the numbers up all sexy-like, a fixed width font for the subtitle is probably a prerequisite. Maybe it'll come in handy one day, but just for fun....

Code:
BlankClip().Subtitle(\
FormatStr(1.005700, "Some Numbers\n", Width=10) + \
FormatStr(6789, "\n", Width=10) + \
FormatStr(206789.1250, "\n", Width=10) + \
FormatStr(67, "\n", Width=10, Keep=true), \
lsp=10, font="courier_new", x=20, y=20)

Last edited by hello_hello; 26th July 2022 at 00:14.
hello_hello is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 21:04.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.